1

我正在尝试创建一个与 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 来改变光标,这将使用户清楚地知道该按钮已被成功单击。

4

0 回答 0