学习了Qt很久,下面总结了5种实现右键菜单的方法(以QListWidget为例):
下面5种方法选其一即可.当然越简单越好啦!
1.重写QListWidget的virtual void mousePressEvent(QMouseEvent *event);鼠标点击函数.
2.重写QListWidget的virtual void contextMenuEvent(QContextMenuEvent *event);右键菜单函数.
3.在使用QListWidget的窗口中,virtual void mousePressEvent(QMouseEvent *event);鼠标点击函数.
4.修改QListWidget的右键菜单策略.
5.添加事件过滤器.
1.重写QListWidget.
//"QMyListWidget.h"
#ifndef QMYLISTWIDGET_H
#define QMYLISTWIDGET_H
#include <QListWidget>
#include <QMenu>
#include <QAction>
#include <QContextMenuEvent>
#include <QMouseEvent>
class QMyListWidget : public QListWidget
{
Q_OBJECT
public:
QMyListWidget(QWidget *parent);
~QMyListWidget();
protected:
void mousePressEvent(QMouseEvent *event);
private:
QMenu *m_contextMenu;
QAction *m_addAction;
QAction *m_delAction;
};
#endif // QMYLISTWIDGET_H
//这里是QMyListWidget的实现.
//"QMyListWidget.cpp"
#include "QMyListWidget.h"
QMyListWidget::QMyListWidget(QWidget *parent)
: QListWidget(parent)
{
//创建一个菜单,后面不在解释.
m_contextMenu = new QMenu;
m_addAction = new QAction("add Item",this);
m_delAction = new QAction("del Item",this);
m_contextMenu->addAction(m_addAction);
m_contextMenu->addAction(m_delAction);
}
QMyListWidget::~QMyListWidget()
{
}
void QMyListWidget::mousePressEvent(QMouseEvent *event)
{
//确保右键点击,然后跳出菜单.
if (event->button() == Qt::RightButton)
{
m_contextMenu->exec(event->globalPos());
}
//要继续保留QListWidget原有的点击事件.
QListWidget::mousePressEvent(event);
}
当重写后,别忘记把QListWidget部件提示为你的QMyListWidget部件,提升方法看上篇博客.
2.重写virtual void contextMenuEvent(QContextMenuEvent *event);
//"QMyListWidget.h"头文件基本一致,所以就不放上来了.
//下面是"QMyListWidget.cpp"的代码.
void QMyListWidget::contextMenuEvent(QContextMenuEvent *event)
{
//让菜单移动到鼠标位置并显示.
m_contextMenu->exec(event->globalPos());
}
3.在原窗口中重写void contextMenuEvent(QContextMenuEvent event);或者void mousePressEvent(QMouseEvent *event);
//以下为"c.cpp"的代码:
c::c(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
ui.listWidget->addItem("zx");
m_contextMenu = new QMenu;
m_addAction = new QAction("add Item", this);
m_delAction = new QAction("del Item", this);
m_contextMenu->addAction(m_addAction);
m_contextMenu->addAction(m_delAction);
}
c::~c()
{
}
void c::contextMenuEvent(QContextMenuEvent *event)
{
//把鼠标位置转化成相对于QWidget的位置,然后判断是否在QListWidget内.
QPoint i = ui.listWidget->mapFromGlobal(event->globalPos());
QRect rect(QPoint(0,0),ui.listWidget->size());
if (rect.contains(i))
{
m_contextMenu->exec(event->globalPos());
}
}*/
4.设置QListWidget的右键菜单策略.
c::c(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//修改策略.
ui.listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
ui.listWidget->addItem("zx");
m_contextMenu = new QMenu;
m_addAction = new QAction("add Item", this);
m_delAction = new QAction("del Item", this);
m_contextMenu->addAction(m_addAction);
m_contextMenu->addAction(m_delAction);
//和该策略对应的信号,showListWidgetMenuSlot为自己定义的槽函数.
connect(ui.listWidget, SIGNAL(customContextMenuRequested(QPoint)),this, SLOT(showListWidgetMenuSlot(QPoint)));
}
c::~c()
{
}
void c::showListWidgetMenuSlot(QPoint pos)
{
m_contextMenu->exec(QCursor::pos());
}
5.使用事件过滤器.假设在窗口中.因为如果在重写类中使用,感觉没什么必要.
c::c(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
ui.listWidget->addItem("zx");
//加入事件过滤器.
ui.listWidget->installEventFilter(this);
m_contextMenu = new QMenu;
m_addAction = new QAction("add Item", this);
m_delAction = new QAction("del Item", this);
m_contextMenu->addAction(m_addAction);
m_contextMenu->addAction(m_delAction);
}
c::~c()
{
}
bool c::eventFilter(QObject *o, QEvent *event)
{
if (o == ui.listWidget)
{
if (event->type() == QEvent::ContextMenu)
{
m_contextMenu->exec(QCursor::pos());
return true;
}
}
return QObject::eventFilter(o,event);
}
好了,原来右键菜单有那么多种的实现~