I need to create a button which has three states:
The logic I want to implement with this button is that whenever this button is clicked, I want the system to go to the intermediate state and wait for an event.
In other way when the state transition is unclicked --> intermediate -- > clicked
and then clicked --> intermediate -->unclicked
.
Does Qt support implementing this kind of button? If so, how?
The nearest you have is QCheckBox
. It already has a property for it: QCheckBox::setTristate
:
auto yourCheckBoxButton = new QCheckBox("Tristate button");
yourCheckBoxButton->setTristate(true);
You can do it on the Designer too (it is at the end of the properties list).
If you don't want to use a QCheckBox
, a stylesheet and a custom property that is modified each time the button is pressed can do it:
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);
});
Other more elaborated options would be to use a QProxyStyle
or to re-implement the QPushButton
class itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With