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