Как реализовать кнопку с тремя состояниями с помощью Qt

Мне нужно создать кнопку, которая имеет три состояния:

  • ненажатый
  • средний
  • щелкнул

Логика, которую я хочу реализовать с помощью этой кнопки, заключается в том, что всякий раз, когда эта кнопка нажата, я хочу, чтобы система переходила в промежуточное состояние и ждала события.

Другими словами, когда переход состояния unclicked --> intermediate -- > clicked, а затем clicked --> intermediate -->unclicked.

Поддерживает ли Qt реализацию такой кнопки? Если да, то как?


person lferasu    schedule 11.07.2017    source источник
comment
как насчет того, чтобы использовать обычную кнопку и придать ей другой цвет (или как-то изменить внешний вид) для промежуточного состояния?   -  person 463035818_is_not_a_number    schedule 11.07.2017
comment
Если вы хотите просто перебрать все состояния, просто создайте кнопку и внутри создайте значение состояния 0, затем с каждым щелчком просто сдвигайте 1 влево или вправо: clicked -> state <<=1 | state >>=1 тогда у вас есть 3 состояния с 0 не нажатым, 1 неопределенный, 2 нажимается   -  person Mateusz    schedule 11.07.2017
comment
Возможна даже попытка переопределить QPushButton.   -  person saeed    schedule 11.07.2017


Ответы (1)


Ближайший у вас есть QCheckBox. Для него уже есть свойство: QCheckBox::setTristate:

auto yourCheckBoxButton = new QCheckBox("Tristate button");
yourCheckBoxButton->setTristate(true);

Вы можете сделать это и в Конструкторе (он находится в конце списка свойств).

Если вы не хотите использовать QCheckBox, это можно сделать с помощью таблицы стилей и пользовательского свойства, которое изменяется при каждом нажатии кнопки:

auto pushButton = new QPushButton("Tristate button");
pushButton->setProperty("state", 0);
pushButton->setProperty("state-step", 1); // change to next state, 1 or -1
pushButton->setStyleSheet("QPushButton[state=\"0\"] { background: red; }"
                          "QPushButton[state=\"1\"] { background: grey; }"
                          "QPushButton[state=\"2\"] { background: blue; }");
connect(pushButton, &QPushButton::clicked, [ = ](bool) {
  const int state = pushButton->property("state").toInt();
  const int step = state == 0 ? 1 :
                   state == 2 ? -1 : pushButton->property("state-step").toInt();
  pushButton->setProperty("state", state + step);
  pushButton->setProperty("state-step", step); // update in case it changed

  // Changing the property is not enough to choose a new style from the stylesheet,
  //  it is necessary to force a re-evaluation
  pushButton->style()->unpolish(pushButton);
  pushButton->style()->polish(pushButton);
});

Другими более сложными вариантами могут быть использование QProxyStyle или повторная реализация QPushButton сам класс.

person cbuchart    schedule 11.07.2017
comment
Три состояния меняют состояние как A -> B -> C -> A... если я хорошо помню, не так ли? Не A -> B -> C -> B -> A как просят. - person ymoreau; 11.07.2017
comment
@ymoreau спасибо, что указали на это, я обновил ответ, чтобы покрыть это - person cbuchart; 11.07.2017