Qt实现右键菜单的五种方法!(以QListWidget为例)

学习了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 
#include 
#include 
#include 
#include 
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);
}

 

你可能感兴趣的:(C++,Qt)