Qt学习之给QPushButton添加菜单CustomContextMenu方法

上篇也说了,题目虽然说是给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);
}
然后编译运行都没问题,但是显示时发现有一个问题:

Qt学习之给QPushButton添加菜单CustomContextMenu方法_第1张图片

菜单显示的位置,并不在光标处。调试查看QPoint的值,发现QPoint的值是光标在界面上的位置,但是菜单显示却是针对显示器来显示的。所以需要转换城全局坐标,可以使用mapToGlobal函数:

void CustomMenu::showMenu(const QPoint &point)
{
	m_menu->exec(mapToGlobal(point));
}
然后重新编译运行,可以看到显示正常:

Qt学习之给QPushButton添加菜单CustomContextMenu方法_第2张图片

点击相应的动作,可以在控制台看到输出:
Qt学习之给QPushButton添加菜单CustomContextMenu方法_第3张图片
完整代码:

#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

你可能感兴趣的:(Qt,Qt学习和实战)