代码之家  ›  专栏  ›  技术社区  ›  Aleph0

Qmenu中的三态Qaction

  •  1
  • Aleph0  · 技术社区  · 6 年前

    我需要支票 QAction ,除了已选中和未选中的模式外,还有部分选中的选项。这基本上已经是Qcheckbox提供的,但不幸的是,Qaction没有提供。

    作为第一次尝试,我通过实现自定义 QWidgetAction .

    三态

    #pragma once
    
    #include <QWidgetAction>
    #include <QCheckBox>
    #include <QLabel>
    #include <QFrame>
    #include <QHBoxLayout>
    
    class TriStateAction : public QWidgetAction {
        Q_OBJECT
    public:
        TriStateAction(QWidget* parent=nullptr) : QWidgetAction(parent) {
            mChkBox = new QCheckBox;
            mChkBox->setTristate(true);
            auto widget = new QFrame;
            widget->setLayout(new QHBoxLayout);
            widget->layout()->addWidget(mChkBox);
            widget->layout()->addWidget(new QLabel("TriState"));
    
            setDefaultWidget(widget);
            connect(mChkBox, &QCheckBox::stateChanged, this, &QWidgetAction::changed);
        }
    
        void setCheckState(Qt::CheckState checkState) {
            mChkBox->setCheckState(checkState);
        }
        Qt::CheckState checkState() const {
            return mChkBox->checkState();
        }
    
    
    private:
        QCheckBox* mChkBox{ nullptr };
    
    };
    

    有了这个简单的测试运行程序:

    主CPP

    #include <QApplication>
    #include <QMenu>
    #include <QAction>
    #include "TriStateAction.h"
    
    int main(int argc, char** args) {
        QApplication app(argc, args);
        auto label=new QLabel("Test");
        label->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
        label->connect(label, &QLabel::customContextMenuRequested, [&](const QPoint& point) {
            QMenu menu(label);
            auto globalPoint = label->mapToGlobal(point);
            auto triStateAction = new TriStateAction();
            auto normalAction = new QAction("Check");
            normalAction->setCheckable(true);
            normalAction->setChecked(true);
            menu.addAction(triStateAction);
            menu.addAction(normalAction);
            menu.exec(globalPoint);
        });
    
        label->show();
        app.exec();
    }
    

    现在,弹出上下文菜单,我可以很高兴地选中、取消选中和部分选中我的三态操作。但是,与普通的Qaction不同,三态在交互时不会关闭菜单。这怎么办?

    另一个问题是我的三态动作的不同布局(视觉表示)。如何才能使它与普通的Qaction更相似?(实际上,这似乎是一个非常困难的问题。)

    1 回复  |  直到 6 年前
        1
  •  1
  •   p-a-o-l-o    6 年前

    行动 了解它的菜单,在您的 main :

    triStateAction->setMenu(&menu);
    

    TriStateAction 类,添加一个槽以捕获复选框 stateChanged 发出信号,然后从那里关闭菜单:

    private slots:
        void checkBoxStateChanged(int)
        {
            if (menu() != nullptr)
            {
                menu()->close();
            }
        }
    

    别忘了连接插槽,在 三态作用 构造函数:

    connect(mChkBox, &QCheckBox::stateChanged, this, &TriStateAction::checkBoxStateChanged);