经常我们会有这样的需求,我们有一些按钮,它们之间是互斥的,也就是说同一时间只有一个被按下。我们可以使用 QButtonGroup 的 setExclusive 实现这个功能。

但是有时我们在这个基础上,还希望所有的这些按钮都不被按下,就像 MATLAB 画图工具里的放大、缩小和移动按钮一样。但是很不幸,通过 QButtonGroup 好像很难做到这一点。

参考 Alternative to QButtonGroup that allows no selection?,我们可以通过自定义按钮来实现这个功能,具体代码如下:

// MyToolButton.h
#pragma once

#include <QToolButton>

class MyToolButton : public QToolButton
{
    Q_OBJECT

public:
    explicit MyToolButton(QObject *parent = nullptr);

protected:
    void mousePressEvent(QMouseEvent *e) override;
};

// MyToolButton.cpp
#include "MyToolButton.h"

#include <QButtonGroup>

MyToolButton::MyToolButton(QObject *parent) : QToolButton(parent) {}

void MyToolButton::mousePressEvent(QMouseEvent *e) {
    do {
        auto button_group = this->group();
        if(nullptr == button_group) {
            break;
        }
        if(!this->isCheckable()) {
            break;
        }
        auto checked_button = button_group->checkedButton();
        if(nullptr == checked_button) {
            break;
        }
        if(checked_button == this) {
            button_group->setExclusive(false);
            this->setChecked(false);
            button_group->setExclusive(true);
            return;
        }
    } while(false);

    QToolButton::mousePressEvent(e);
}