上篇也说了,题目虽然说是给QPushButton添加鼠标右键菜单,其实对于所有的QWidget都是适用的。之所以说QPushButton,是以QPushButton为例进行实现,写的类继承自QPushButton。上篇是说使用ActionsContextMenu,现在换一种方法来实现给QWidget添加右键菜单。下面的方法是使用CustomContextMenu方式来实现。
使用CustomContextMenu方式添加右键菜单,要实现一个QMenu,里面包含你需要的QAction,使用ActionsContextMenu就只需要包含自己需要的QAction就可以了,并不需要创建一个QMenu。
首先在头文件中声明成员变量,并包含所需要的头文件:
private:
QMenu *m_menu;
QAction *m_actionOne;
QAction *m_actionTwo;
QAction *m_actionThree;
声明所需要的槽函数:最上面的槽函数是用来显示菜单所需要的,另外三个是三个QAction所对应的槽:
protected slots:
void showMenu(const QPoint &point);
void actionOneSlot();
void actionTwoSlot();
void actionThreeSlot();
在构造函数中,需要设置使用菜单的策略:
setContextMenuPolicy(Qt::CustomContextMenu);
然后是创建QMenu和QAction,将QAction添加到QMenu并设置Action的名称和连接对应的槽函数:
m_menu = new QMenu(this);
m_actionOne = new QAction(this);
m_actionTwo = new QAction(this);
m_actionThree = new QAction(this);
m_actionOne->setText("ActionOne");
m_actionTwo->setText("ActionTwo");
m_actionThree->setText("ActionThree");
m_menu->addAction(m_actionOne);
m_menu->addAction(m_actionTwo);
m_menu->addAction(m_actionThree);
connect(m_actionOne, SIGNAL(triggered()), this, SLOT(actionOneSlot()));
connect(m_actionTwo, SIGNAL(triggered()), this, SLOT(actionTwoSlot()));
connect(m_actionThree, SIGNAL(triggered()), this, SLOT(actionThreeSlot()));
接下来是和设置使用菜单策略同样重要的,连接菜单请求信号以及显示菜单的槽,可以看到是以点(QPoint)为参数的,也就是鼠标Cursor光标所在的位置:
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showMenu(const QPoint&)));
接下来是实现QAction对应的槽函数,以及显示菜单的槽,前者上一篇已经提到,下面只说显示菜单的槽函数:接收到信号传过来的QPoint后,给QMenu显示使用:
void CustomMenu::showMenu(const QPoint &point)
{
m_menu->exec(point);
}
然后编译运行都没问题,但是显示时发现有一个问题:
菜单显示的位置,并不在光标处。调试查看QPoint的值,发现QPoint的值是光标在界面上的位置,但是菜单显示却是针对显示器来显示的。所以需要转换城全局坐标,可以使用mapToGlobal函数:
void CustomMenu::showMenu(const QPoint &point)
{
m_menu->exec(mapToGlobal(point));
}
然后重新编译运行,可以看到显示正常:
#include
#include
#include
#include
class CustomMenu : public QPushButton
{
Q_OBJECT
public:
CustomMenu(QWidget *parent = 0);
~CustomMenu();
protected slots:
void showMenu(const QPoint &point);
void actionOneSlot();
void actionTwoSlot();
void actionThreeSlot();
private:
QMenu *m_menu;
QAction *m_actionOne;
QAction *m_actionTwo;
QAction *m_actionThree;
};
#include "custommenu.h"
CustomMenu::CustomMenu(QWidget *parent)
: QPushButton(parent)
{
setContextMenuPolicy(Qt::CustomContextMenu);
m_menu = new QMenu(this);
m_actionOne = new QAction(this);
m_actionTwo = new QAction(this);
m_actionThree = new QAction(this);
m_actionOne->setText("ActionOne");
m_actionTwo->setText("ActionTwo");
m_actionThree->setText("ActionThree");
m_menu->addAction(m_actionOne);
m_menu->addAction(m_actionTwo);
m_menu->addAction(m_actionThree);
connect(m_actionOne, SIGNAL(triggered()), this, SLOT(actionOneSlot()));
connect(m_actionTwo, SIGNAL(triggered()), this, SLOT(actionTwoSlot()));
connect(m_actionThree, SIGNAL(triggered()), this, SLOT(actionThreeSlot()));
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showMenu(const QPoint&)));
}
CustomMenu::~CustomMenu()
{
}
void CustomMenu::showMenu(const QPoint &point)
{
m_menu->exec(mapToGlobal(point));
}
void CustomMenu::actionOneSlot()
{
qDebug() << "actionOne";
}
void CustomMenu::actionTwoSlot()
{
qDebug() << "actionTwo";
}
void CustomMenu::actionThreeSlot()
{
qDebug() << "actionThree";
}
#include "custommenu.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
CustomMenu b(&w);
b.setText("Button");
w.show();
return a.exec();
}
源码下载: http://download.csdn.net/detail/u011417605/9466404
本文地址:http://blog.csdn.net/u011417605/article/details/50929986
交流QQ:1245178753