Qt中QWidgetAction使用例子

发布时间 2023-12-12 08:46:26作者: 兜尼完

在Qt中可以用QWidgetAction来模仿现代应用程序中的自定义控件的菜单项。比如下方Edge浏览器的菜单,在“缩放”一项中有用来调整网页缩放的几个按钮和显示网页缩放比例的控件。

这样的菜单项Qt也可以做。下面将给出一个简单的例子供参考,此例子在VS2017和Qt5.9下测试通过。其运行效果如下图:

上方图片中“复制”、“粘贴”和红色正方形就是我们自定义的菜单项内容。源代码的头文件如下:

class MWidget : public QWidget
{
    Q_OBJECT

public:
    MWidget(QWidget* parent = 0);

private:
    void paintEvent(QPaintEvent* event) override;
    void mousePressEvent(QMouseEvent* event) override;
    void mouseReleaseEvent(QMouseEvent* event) override;
};

CPP文件:

// 这是弹出右键菜单的槽函数
void QtTest::on_tvHost_customContextMenuRequested(const QPoint& pos)
{
    QMenu *menu = new QMenu;

    QWidgetAction* actOpera = new QWidgetAction(menu);
    QWidget* mainHost = new QWidget;
    QHBoxLayout* layout = new QHBoxLayout(mainHost);
    layout->setContentsMargins(4, 0, 4, 0);
    layout->setSpacing(2);
    layout->addWidget(new QPushButton(u8"复制"));
    layout->addWidget(new QPushButton(u8"粘贴"));
    layout->addWidget(new MWidget());
    mainHost->setLayout(layout);
    actOpera->setDefaultWidget(mainHost);

    menu->addAction(actOpera);
    menu->addAction(u8"速览定义(&W)");
    menu->addAction(u8"转到定义(&S)");
    menu->addAction(u8"注释(&C)");
    menu->addAction(u8"断点(&B)");
    menu->exec(ui.tvHost->mapToGlobal(pos));
    delete menu;
}

/////////////////////////////////////////////////////////////////////////////////////////

// 这个自定义控件只是一个例子可以不要
MWidget::MWidget(QWidget* parent) : 
    QWidget(parent)
{
    setFixedSize(22, 22);
}

void MWidget::paintEvent(QPaintEvent* event)
{
    QPainter painter(this);
    painter.fillRect(rect(), Qt::red);
}

void MWidget::mousePressEvent(QMouseEvent* event)
{
    // 防止鼠标点击后菜单自动关闭
}

void MWidget::mouseReleaseEvent(QMouseEvent* event)
{
    // 防止鼠标点击后菜单自动关闭
}

上述代码中最重要的内容在QtTest::on_tvHost_customContextMenuRequested(...)函数中。其中QtTest是主窗口类。tvHost是需要弹出右键菜单的控件,需要在Qt设计师软件里将此控件的右键菜单模式修改为CustomContextMenu,然后运行时在控件上方点击右键就会自动触发这个槽函数。MWidget是我特意添加的一个自定义控件例子,如注释内容所说,如果你重写了mousePressEvent(...)和mouseReleaseEvent(...)函数,那么在你点击这个控件时右键菜单不会自动消失。否则,只要鼠标在此控件上点击一次菜单就会自动关闭,如同点击普通的QAction一样。这种行为在我的电脑上测试是这样,不知道其它的系统是不是也这样。

当然,QWidgetAction也有另外一种使用方式。就是自定义一个类继承它,然后向其中添加内容。这里不详细说了,可以自行搜索相关例子。