(在上一篇文章中写了关于鼠标右键的内容,主要是想简单的实现关闭程序和最小化程序的功能,但我回过头来再看上篇文章时,发现了一些小问题,以及没交代清楚的事情。)
在Qt中,contextMenuEvent是一个事件处理函数,用于处理右键菜单事件。默认情况下,它会创建并显示一个标准的上下文菜单(QMenu),但你也可以根据需要自定义菜单的内容和行为。
虽然一般情况下我们使用QMenu作为右键菜单的容器,但并不是一定要借助Menu。你可以选择使用其他的QWidget子类作为菜单的容器,例如QToolBar、QComboBox等。这样做的好处是可以实现更加自由和灵活的菜单界面。
当然,如果你只是需要简单的右键菜单,使用QMenu是最常见和方便的方式。你可以通过创建QAction对象,添加到QMenu中,并通过addAction()方法将QAction添加到QMenu中。然后,可以使用exec()方法显示菜单,并根据用户的选择执行相应的操作。
总而言之,contextMenuEvent函数的目的是处理右键菜单事件,而使用QMenu是最常见和方便的方法,但你也可以选择其他QWidget子类作为菜单的容器,以满足特定的需求。
一:contextMenuEvent函数的准备工作
需要在使用前在类中重写,并引入头文件#include <QContextMenuEvent>
mainwindow.h:
#include <QMainWindow>
#include <QContextMenuEvent> //引入头文件
#include <QMouseEvent>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
void contextMenuEvent(QContextMenuEvent* event); //重写contextMenuEvent函数
~MainWindow();
private:
Ui::MainWindow *ui;
};
二:定义contextMenuEvent函数
这里注意下,我要实现的内容是关闭和最小化程序,所以这里我用的一个menu。contextMenuEvent是一个事件处理函数,用于处理右键菜单事件。默认情况下,它会创建并显示一个标准的上下文菜单(QMenu),但你也可以根据需要自定义菜单的内容和行为。
你可以选择使用其他的QWidget子类作为菜单的容器,例如QToolBar、QComboBox等。这样做的好处是可以实现更加自由和灵活的菜单界面。
当然,如果你只是需要简单的右键菜单,使用QMenu是最常见和方便的方式。你可以通过创建QAction对象,添加到QMenu中,并通过addAction()方法将QAction添加到QMenu中。然后,可以使用exec()方法显示菜单,并根据用户的选择执行相应的操作。
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
void MainWindow::contextMenuEvent(QContextMenuEvent* event)
{
// 创建菜单
QMenu menu(this);
// 添加动作到菜单
QAction *closeAction = menu.addAction("退出");
QAction *miniAction = menu.addAction("最小化");
// 显示菜单,并获取用户选择的动作
QAction *selectedAction = menu.exec(event->globalPos());
// 如果用户选择了动作,则执行相应的槽函数
if(selectedAction) {
if(selectedAction == closeAction) {
close();
} else if(selectedAction == miniAction) {
showMinimized();
}
}
}
在这里有两个陌生的东西:globalPos()和exec()
globalPos()
通常用于获取鼠标事件的全局坐标。要使用 globalPos()
函数,您需要包含 Qt 的头文件,并且通常使用 QMouseEvent,所以引入#include <QMouseEvent>。
QMenu的exec()方法用于显示菜单并等待用户选择。它会阻塞当前线程,直到用户选择了一个菜单项或者取消了菜单。当你调用menu.exec(event->globalPos())时,菜单会显示在鼠标右击事件发生的位置(event->globalPos()返回的是全局坐标)。然后,exec()方法会开始一个事件循环,并等待用户选择菜单项。
一旦用户选择了菜单项,exec()方法会返回对应的QAction对象,表示用户的选择。你可以通过检查返回的QAction指针是否为nullptr,来判断用户是否选择了有效的菜单项。然后,你可以根据选择的菜单项执行相应的操作。
需要注意的是,exec()方法是一个模态的方法,会阻塞当前线程。因此,如果在执行exec()之后还有需要处理的代码,你可能需要将exec()方法放在一个单独的线程中,或者使用信号与槽机制来处理选择菜单项后的操作。
三:还可以进一步优化
在上面代码中可以看到,在MainWindow::contextMenuEvent()中声明了QAction的指针变量,这意味着我每次点击鼠标右键的时候都会声明一次这些指针变量,这可能会导致额外的内存分配和释放操作,从而影响性能。所以代码做如下更改:
mainwindow.h:
#include <QMainWindow>
#include <QMenu>
#include <QMouseEvent>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QMenu menu;
QAction* closeAction,*miniAction,*selectedAction;
void contextMenuEvent(QContextMenuEvent* event);
};
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 创建菜单动作,将动作添加到菜单中
closeAction = menu.addAction("退出");
miniAction = menu.addAction("最小化");
}
void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
selectedAction = menu.exec(event->globalPos());
if(selectedAction == closeAction){
close();
}else if(selectedAction == miniAction){
showMinimized();
}
}