欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

Qt系列文章之 右键菜单QMenu(上)

发布时间:2023/12/20 编程问答 57 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Qt系列文章之 右键菜单QMenu(上) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

上一篇文章介绍了自定义用户窗体并提升到ui文件中的操作流程,本文介绍用户界面上常用的右键菜单栏的创建。

右键菜单QMenu

用户界面鼠标交互是十分常见的人机交互形式,大部分窗体软件都具备类似右键鼠标出现一个菜单栏,用户可选择需要的操作动作。本文基于上一文的场景,介绍如何在一个表格窗体中右键出现一个用户可以选择动作的菜单栏。由于右键动作只是针对表格窗体,必然这个菜单栏也需要在用户自定义窗体中进行开发,作为用户窗体属性的一部分。

首先在用户窗体的头文件之中包含需要的两个头文件:

#include <QMenu> #include <QAction>

然后在私有属性中定义一个QMenu对象指针:

private:QMenu *m_menu; //新建一个Menu属性

在CPP文件中的构造函数中为菜单指针初始化空间,注意QMenu传入的参数是this,这样将用户窗体作为菜单的父类,进入父类的继承体系,在父类析构时会先自动析构其所有子类,因此在析构函数中就没有必要对m_menu进行空间释放。

CustomTableWidget::CustomTableWidget(QWidget *parent):QTableWidget(parent),m_menu(new QMenu(this)) {

然后定义几个菜单动作:

QAction * addRow = new QAction("Add one row"); //定义为表格添加一行的动作QAction * removeRow = new QAction("Remove one row"); //定义从表格中删除一行的动作QAction *removeAllRow = new QAction("Remove all rows"); //定义删除表格所有行动作

将定义好的动作添加到菜单之中:

m_menu->addAction(addRow); //添加动作到菜单m_menu->addAction(removeRow); //添加动作到菜单m_menu->addSeparator(); //添加一个分隔符m_menu->addAction(removeAllRow); //添加动作到菜单

当用户在表格中鼠标点击右键时,在鼠标点击的位置出现定义的菜单,那么有三个问题需要具体考虑:如何获取鼠标点击了右键,第二如何获取鼠标位置,第三如何交互式显示菜单。

如何获取鼠标点击了右键,可以参考上一文中对鼠标输入控件的捕捉:

else if (event->button()==Qt::RightButton) //捕获鼠标右键输入{

如何获取鼠标位置,从代码中看,唯一能够和鼠标位置有关系的只能是QMouseEvent对象。观看一下QMouseEvent提供的方法有两个和位置相关,pos()和globalPos(),具体那个合适,可以自行阅读方法的帮助。 其实最好的方法就是都试用一下,测试之后就会明白:

此处先试用pos()来获取鼠标的位置。

else if (event->button()==Qt::RightButton) //捕获鼠标右键输入{QPoint mousePos = event->pos(); //获取鼠标位置

如何显示菜单,可以阅读QMemu的帮助,有一个方法exec(),其输入就是一个位置QPOint:

根据提示,显示菜单:

else if (event->button()==Qt::RightButton) //捕获鼠标右键输入{QPoint mousePos = event->pos(); //获取鼠标位置m_menu->exec(mousePos); //显示菜单}

编译运行代码,在表格窗体之中点击鼠标右键,看看界面会发生什么:

有意思的是菜单并没有显示在表格窗体之中,而是显示在窗体之外。显然使用pos()函数获取鼠标位置是不对的,需要使用globalPos()。 pos()获取的是鼠标在子窗体局部坐标系的位置,globalPos()获取的是鼠标在操作系统桌面全局坐标系下的位置。而菜单对象的exec()函数需要的参数是全局坐标系下的位置。 将代码进行修改:

void CustomTableWidget::mousePressEvent(QMouseEvent *event) {if(event->button()==Qt::LeftButton){qDebug()<<"table mouse press event";}else if (event->button()==Qt::RightButton) //捕获鼠标右键输入{QPoint mousePos = event->globalPos(); //此处调用鼠标的globalPos()而不是pos(),pos()输出是相对当前子窗体的位置m_menu->exec(mousePos); //显示菜单}return QTableWidget::mousePressEvent(event); //记得返回基类的时间处理函数 }

编译运行代码,再在窗体点击鼠标右键,观察界面的响应:

本文用户表格窗体的h文件代码:

#ifndef CUSTOMTABLEWIDGET_H #define CUSTOMTABLEWIDGET_H #include <QMouseEvent> #include <QMenu> #include <QAction>#include <QTableWidget> //手动包含class CustomTableWidget : public QTableWidget {Q_OBJECT public:CustomTableWidget(QWidget *parent = nullptr);protected:void mousePressEvent(QMouseEvent *event) override;private:QMenu *m_menu; //新建一个Menu属性 };#endif // CUSTOMTABLEWIDGET_H

本文用户表格窗体的cpp文件代码:

#include "customtablewidget.h" #include <QDebug>CustomTableWidget::CustomTableWidget(QWidget *parent):QTableWidget(parent),m_menu(new QMenu(this)) {QAction * addRow = new QAction("Add one row"); //定义为表格添加一行的动作QAction * removeRow = new QAction("Remove one row"); //定义从表格中删除一行的动作QAction *removeAllRow = new QAction("Remove all rows"); //定义删除表格所有行动作m_menu->addAction(addRow); //添加动作到菜单m_menu->addAction(removeRow); //添加动作到菜单m_menu->addSeparator(); //添加一个分隔符m_menu->addAction(removeAllRow); //添加动作到菜单 }void CustomTableWidget::mousePressEvent(QMouseEvent *event) {if(event->button()==Qt::LeftButton){qDebug()<<"table mouse press event";}else if (event->button()==Qt::RightButton) //捕获鼠标右键输入{QPoint mousePos = event->globalPos(); //此处调用鼠标的globalPos()而不是pos(),pos()输出是相对当前子窗体的位置m_menu->exec(mousePos); //显示菜单}return QTableWidget::mousePressEvent(event); //记得返回基类的时间处理函数 }

下一文将继续介绍QMenu怎么实现Action和表格操作的关联。


欢迎同好沟通交流,批评指正,欢迎关注我的公号:不如起而行之

总结

以上是生活随笔为你收集整理的Qt系列文章之 右键菜单QMenu(上)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。