我正在尝试创建一个与 QComboBox 具有类似行为的小部件,但根据用户是单击小部件上的箭头还是其他位置而具有不同的行为。对于初学者,我将小部件本身建模为一个宽 QPushButton,并在其上叠加一个 QToolButton。一旦我看到了我想要的样子,我将添加一个 QListView 来提供下拉菜单,并使其在单元按下 QToolButton(但不是 QPushButton)时出现。到目前为止,我的基本测试代码如下所示:
#include <QtWidgets/QApplication>
#include <QDialog>
#include <QPushButton>
#include <QToolButton>
#include <QPushButton>
#include <QGridLayout>
class StylesheetTest : public QDialog
{
Q_OBJECT
public:
StylesheetTest(QWidget * parent = nullptr) : QDialog(parent)
{
// Create the widgets and layouts
itsLayout = new QGridLayout;
itsMainButton = new QPushButton;
itsDropdownButton = new QToolButton;
// Place the widgets in the layout:
itsLayout -> addWidget(itsMainButton, 0, 0, 1, 2);
itsLayout -> addWidget(itsDropdownButton, 0, 1, 1, 1);
itsLayout -> setSpacing(0);
itsLayout -> setColumnStretch(0, 1);
itsMainButton -> setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
itsDropdownButton -> setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
itsDropdownButton -> setArrowType(Qt::DownArrow);
// Formally appoint the layout
setLayout(itsLayout);
// Now the stylesheet settings
setStyleSheet("QToolButton { border: none; } ");
// Give the button a label
itsMainButton -> setText("An extraordinarily long label for a button");
}
private:
QPushButton *itsMainButton;
QToolButton *itsDropdownButton;
QGridLayout *itsLayout;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
StylesheetTest t;
t.show();
return a.exec();
}
#include "main.moc"
这让我大部分时间都在那里;生成的按钮如下所示:
它看起来很像一个 QComboBox,但我得到了 QPushButton 和 QToolButton 的独立行为,就像我想要的那样。但是,我想让它变得更好:
- 我想在 QPushButton 的右侧设置一点边距,以便文本不会与箭头重叠
- 我希望箭头本身小一点
我所知道的关于样式表的一切(诚然不多)告诉我,要实现这一点,我需要类似的东西
// Now the stylesheet settings
setStyleSheet("QPushButton { padding-right: 20px; }");
setStyleSheet("QToolButton { border: none; } "
"QToolButton::down-arrow { width: 8px; height: 8px; }" );
但实际上这样做的结果是一团糟:
进一步的实验表明,尝试将 QPushButton 的 'padding-right' 参数设置为任何值都会导致其垂直高度以这种方式受到挤压,而所有修改向下箭头大小的尝试都失败了。我显然做错了什么,但我看不出是什么。任何提示将不胜感激。
更新
我决定一个更好的方法是,而不是在 QPushButton 前面使用 QToolButton 并手动实现 QListView 行为,而是将 QPushButton 放在 QComboBox 前面,只让后者的箭头暴露。像这样:
#include <QtWidgets/QApplication>
#include <QDialog>
#include <QPushButton>
#include <QComboBox>
#include <QGridLayout>
class StylesheetTest : public QDialog
{
Q_OBJECT
public:
StylesheetTest(QWidget * parent = nullptr) : QDialog(parent)
{
// Create the widgets and layouts
itsLayout = new QGridLayout;
itsMainButton = new QPushButton;
itsHiddenComboBox = new QComboBox;
// Place the widgets in the layout:
itsLayout -> addWidget(itsHiddenComboBox, 0, 0, 1, 3);
itsLayout -> addWidget(itsMainButton, 0, 0, 1, 2);
itsLayout -> setSpacing(0);
itsLayout -> setColumnStretch(0, 1);
itsLayout -> setColumnMinimumWidth(2, 20);
itsMainButton -> setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
itsHiddenComboBox -> setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
// Formally appoint the layout
setLayout(itsLayout);
// Now the stylesheet settings
setStyleSheet("QPushButton { border: none; padding-left: 10px; } ");
itsMainButton -> setText("An extraordinarily long label for a button");
}
private:
QPushButton *itsMainButton;
QComboBox *itsHiddenComboBox;
QGridLayout *itsLayout;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
StylesheetTest t;
t.show();
return a.exec();
}
#include "main.moc"
该解决方案的一个缺点是,在消除了 QPushButton 的边框后,它不再对被单击做出明显响应(即使发送了通常的信号)。这已在其他地方记录:请参见此处。碰巧我可以解决这个问题,因为我的最终目的是按下 QPushButton 来改变光标,这将使用户清楚地知道该按钮已被成功单击。