Применение таблицы стилей Qt к QPushButton и QToolButton

Я пытаюсь создать виджет, который будет иметь поведение, аналогичное 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; }" );

но на самом деле результатом этого является беспорядок:

Вторая попытка - намного хуже

Дальнейшие эксперименты показывают, что попытка установить параметр "padding-right" QPushButton на любое значение вообще приводит к тому, что его вертикальная высота уменьшается таким образом, в то время как все попытки изменить размер стрелки вниз заканчиваются неудачей. Я, очевидно, делаю что-то не так, но я не вижу, что. Любые советы будут с благодарностью приняты.

ОБНОВИТЬ

Я решил, что лучше, чем использовать QToolButton перед QPushButton и вручную реализовывать поведение 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, чтобы вызвать изменение курсора, и это сделает для пользователя достаточно очевидным, что кнопка была успешно нажата.

0 ответов

Другие вопросы по тегам