QT小项目--天气预报桌面小程序(鼠标右击事件2)

        (在上一篇文章中写了关于鼠标右键的内容,主要是想简单的实现关闭程序和最小化程序的功能,但我回过头来再看上篇文章时,发现了一些小问题,以及没交代清楚的事情。)

        在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();
    }
}

  • 38
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值