如何使用Qt实现一个三态按钮

3
我需要创建一个具有三种状态的按钮:
  • 未点击
  • 中间状态
  • 已点击
我想要实现的逻辑是,每当该按钮被点击时,系统将进入中间状态并等待事件。
换句话说,当状态转换为未点击 --> 中间状态 --> 已点击,然后已点击 --> 中间状态 --> 未点击
Qt是否支持实现这种类型的按钮?如果是,如何实现?

2
使用普通按钮,为中间状态设置不同的颜色(或以某种方式改变外观),如何? - 463035818_is_not_a_number
如果你只想遍历所有的状态,那么只需要创建一个按钮,在里面创建一个状态值为 0,然后每次点击时将其向左或向右移动 1 个单位:clicked -> state <<=1 | state >>=1 ,这样就有了 3 种状态,其中 0 表示未选中,1 表示不确定,2 表示已选中。 - mrogal.ski
甚至可能的尝试是重新实现QPushButton。 - saeed
1个回答

6
你最接近的是 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类本身。

三态正在像“A -> B -> C -> A”这样改变状态……如果我没记错的话,是吗?而不是像要求的那样“A -> B -> C -> B -> A”。 - ymoreau
@ymoreau 谢谢您指出这一点,我已经更新了答案来涵盖它。 - cbuchart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接