An alternative to QButtonGroup that does not allow you to choose?

I am writing a C ++ based application qt. I have several buttons that I want to be mutually exclusive - only one can be switched at a time. I usually use QButtonGroup - it provides a good logical way to manage button sets. When someone clicks, the previous click is clicked, which is exactly the behavior I want.

This time, however, I would like the group to be completely disconnected. Unfortunately, this seems to be forbidden QButtonGroup:

exclusive: bool

This property contains whether an exclusive group of buttons.

If this property is true, then only one button in the group can be checked at any time. The user can press any button to check it, and this button will replace the existing one as checked in the group.

In an exclusive group, the user cannot uncheck the current flag by clicking on it; instead, another button in the group must be clicked to set a new marked button for this group.

Of course, there are several ways around this. I am wondering if there is a pre-made alternative QButtonGroupthat allows this behavior, so 1) I do not reinvent the wheel and 2) I can stay within the idiomatic limits qtto simplify project management in the future.

Any suggestions?

+5
source share
4

, , . , Qt3 . Qt4 Qt5, .

, , CustomWidget -, ( CustomButton), . , , .

, CustomWidget, QButtonGroup :

QButtonGroup* m_ButtonGroup = new QButtonGroup(this);
m_ButtonGroup->hide();
m_ButtonGroup->insert(Btn1);
m_ButtonGroup->insert(Btn2);
m_ButtonGroup->insert(Btn3);
m_ButtonGroup->setExclusive(true);

Btn1, Btn2 Btn3 CustomButton

class CustomButton : public QToolButton
{
    Q_OBJECT

  public:
    CustomButton (QWidget* apo_parent = 0, const char* as_name = 0);
    virtual ~CustomButton ();

  protected:
    virtual void mousePressEvent(QMouseEvent* a_Event);
};

, , - mousePressEvent. :

void CustomButton ::mousePressEvent(QMouseEvent* a_Event)
{
  if(group() && isToggleButton())
  {
    CustomButton* selectedButton(dynamic_cast<CustomButton*>(group()->selected()));
    if(selectedButton)
    {
      if(selectedButton->name() == name())
      {
        group()->setExclusive(false);
        toggle();
        group()->setExclusive(true);
        return;
      }
    }
  }
  QToolButton::mousePressEvent(a_Event);
}

, .

+1

Qt5 Laurent Michel, release :

// Allow to uncheck button in exclusive group
void CustomButton::mouseReleaseEvent(QMouseEvent* a_Event) {
    if(group()->checkedId()==group()->id(this)) {
        if(isDown()) group()->setExclusive(false);
    }
    QToolButton::mouseReleaseEvent(a_Event);
    group()->setExclusive(true);
}
+2

, , nextCheckState() :

void MyButton::setSemiExclusive(bool value)
{
  mSemiExclusive = value;
}

void MyButton::nextCheckState()
{
  if (mSemiExclusive)
  {
    if (auto g = group())
    {
      auto old = g->exclusive();
      if (g->checkedButton() != this)
        g->setExclusive(true);

      QAbstractButton::nextCheckState();
      g->setExclusive(old);
      return;
    }
  }

  QAbstractButton::nextCheckState();
}

It depends on what the QButtonGroupassociated group QButtonGroupset exclusiveto false.

+1
source

If you do not want to extend the button class, you can also do this with signals (Qt5, Python):

from PySide import QtGui

class View(QtGui.QWidget):
    def __init__(self):
        self.buttonGroup = QtGui.QButtonGroup(self)
        for button in buttons:
            self.buttonGroup.addButton(button)
            button.pressed.connect(buttonPressed)
            button.released.connect(buttonReleased)

    def buttonPressed(self):
        button = self.sender()
        checkedButton = self.buttonGroup.checkedButton()
        if checkedButton != None and checkedButton.objectName() == button.objectName():
            self.buttonGroup.setExclusive(False)

    def buttonReleased(self):
        button = self.sender()
        if self.buttonGroup.exclusive() == False:
            button.setChecked(False)
            self.buttonGroup.setExclusive(True)

    def manualDeselection:
        self.buttonGroup.setExclusive(False)
        self.buttonGroup.checkedButton().setChecked(False)
        self.buttonGroup.setExclusive(True)
+1
source

All Articles