所谓“右键菜单”,我们可以这样来看:右键+菜单。所以我们可以定义一个菜单,然后重写鼠标点击事件,令菜单在鼠标右击的时候弹出来。这种方法是可以的,但是Qt提供了一种专门用于右键菜单的方法,且看下面这个属性:
Qt::ContextMenuPolicy
通过函数setContextMenuPolicy()来设置一个widget上面显示的菜单的属性。
1.Qt::DefaultContextMenu
这个属性的默认值是Qt::DefaultContextMenu,此时需要调用函数contextMenuEvent(),重写其中的内容。
void MenuTest::contextMenuEvent(QContextMenuEvent *) { QMenu *menu = new QMenu(this); menu->addAction(tr("花好月圆")); menu->addAction(tr("似水流年")); menu->exec(QCursor::pos()); }
这个属性的其它值有Qt::NoContextMenu、Qt::PreventContextMenu、Qt::ActionsContextMenu以及Qt::CustomContextMenu。
2.Qt::ActionsContextMenu
ui.treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);//设置属性 QAction *act1 = new QAction(tr("灯"), this); ui.treeWidget->addAction(act1); QAction *act2 = new QAction(tr("红"), this); ui.treeWidget->addAction(act2);
这种方法也很简单,但依然不够灵活。
3.Qt::CustomContextMenu
使用Qt::CustomContextMenu时会发出信号 customContextMenuRequested()。通过该信号,可以获得当前鼠标的位置,通过位置可以做更多我们想做的事。下面是一个简单的完整的例子。
头文件:
#ifndef MENUTEST_H #define MENUTEST_H #pragma execution_character_set("utf-8") #include <QtWidgets/QWidget> #include <QMenu> #include "ui_menutest.h" class MenuTest : public QWidget { Q_OBJECT public: MenuTest(QWidget *parent = 0); ~MenuTest(); private: Ui::MenuTestClass ui; QMenu *m_pCustomMenu;//右键菜单 private slots: void TreeWidgetMenuSlot(const QPoint &);//鼠标右击,弹出菜单槽函数 void MenuActionSlot(QAction *);//点击菜单中项的槽函数 }; #endif // MENUTEST_H
具体实现:
#include <QDebug> #include "menutest.h" MenuTest::MenuTest(QWidget *parent) : QWidget(parent) , m_pCustomMenu(NULL) { ui.setupUi(this); ui.treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);//设置属性 //右击时会发出信号,然后建立槽连接 connect(ui.treeWidget, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(TreeWidgetMenuSlot(const QPoint &))); } MenuTest::~MenuTest() { } void MenuTest::TreeWidgetMenuSlot(const QPoint &) { if (m_pCustomMenu == NULL) { m_pCustomMenu = new QMenu(this); connect(m_pCustomMenu, SIGNAL(triggered(QAction *)), this, SLOT(MenuActionSlot(QAction *))); } m_pCustomMenu->clear(); QAction *act1 = new QAction(tr("灯"), m_pCustomMenu); act1->setData(1); m_pCustomMenu->addAction(act1); QAction *act2 = new QAction(tr("红"), m_pCustomMenu); act2->setData(2); m_pCustomMenu->addAction(act2); QAction *act3 = new QAction(tr("酒"), m_pCustomMenu); act3->setData(3); m_pCustomMenu->addAction(act3); QAction *act4 = new QAction(tr("绿"), m_pCustomMenu); act4->setData(4); m_pCustomMenu->addAction(act4); m_pCustomMenu->popup(QCursor::pos()); } void MenuTest::MenuActionSlot(QAction *act) { if (act == NULL) { return; } int nData = act->data().toInt(); switch (nData) { case 1: qDebug() << "好花好景好时光"; break; case 2: qDebug() << "画堂春暖不胜香"; break; case 3: qDebug() << "红裙舞动燕飞忙"; break; case 4: qDebug() << "一片行云到画堂"; break; default: break; } }
注:上面的例子中使用了switch语句,可能对效率有影响,所以我们可以为每个action建立信号槽连接。
下面是运行效果图——
时间: 2024-10-23 13:18:16