【转】在 QTableWidget 部件上实现鼠标右键响应功能

原文地址  ==> http://realvita.wordpress.com/2008/08/20/retrieving-mousepressevent-from-qtablewidget/


有的时候,我们需要有一个 QTableWidget 在某个 Widget 的内部显示数据或者操作数据。对于一些需求,我们想通过右键或者中键来实现。而 QTableWidget 自己有一个 MousePressEvent 的 event 可以用来处理这些操作。可问题是,当这个 table 放在了一个 Widget 内部的时候,再用在 Visual Stadio 里面,你就无法实现这个函数了。那,怎么解决呢?
 
用 Qt 的 eventFilter() 和 Object 的 installEventFilter() 来实现。
 
首先,要定义你的 eventFilter(),这是用来处理相应事件的函数
MyGui::eventFilter( QObject *object, QEvent *event )
具体例子可以从Qt的帮助里面看。
我的用法是:

if (object == tableWidget->viewport())
{
    if( event->type() == QEvent::MouseButtonPress)
    { 
        // if yes, we need to cast the event into a QMouseEvent type
        QMouseEvent * pMouseEvent = static_cast<QMouseEvent *>(event);
        // check whether it's mid button pressed
        if (pMouseEvent->button() == Qt::MidButton)
        {
            //do the processing and return true
            textBrowserErrorInfo->setText(tr("clicked"));
            return true;   //一定要返回true,如果你不想别的object也能接收到这个event
        }
    }
}


// 注意这里,未处理的事件,要返还给上一级的事件处理函数。
return QWidget::eventFilter(object, event);


关键问题,是要 install 这个 EventFilter。在你的 Widget 的构造函数里面,
(myTableWidget->viewport())->installEventFilter(this);
 
这个用法,就是告诉Qt,QTableWidget 的 viewport() 要处理所有 MyGui 的事件。
这个 viewport() 就是重点。你不可以像帮助中那样,直接用
myTableWidget->installEventFilter(this);
这样的话,你的 QTableWidget 将不会接收到 MousePressEvent 的 event,除非,你在 QTableWidget 四周的那条窄窄的边界上(默认一个 pixel 宽度)点击鼠标。奇怪的是,你可以接收到 Wheel 事件。原因为何,尚未深究。






第二种方法,通过右键菜单方式实现,原文地址  ==> http://edsionte.com/techblog/archives/3014


4.为表格数据添加右键菜单

有时候我们想通过点击鼠标右键对表格数据进行一些其他操作,比如复制、查看详情等,我们可以按照下面的方法来实现。为了实现点击右键弹出菜单这个功能,我们必须在类studentInfo类中声明一个菜单变量popMenu和一个菜单选项变量action。

01classstudentInfo :publicQMainWindow
02{
03…………
04private:
05    Ui::studentInfo *ui;
06    QMenu *popMenu;
07    QAction *action;
08  
09privateslots:
10    voidon_stuTableWidget_customContextMenuRequested(QPoint pos);
11…………
12};

声明完毕后,我们在studentInfo类的构造函数中对其进行初始化,如下:

1ui->stuTableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
2popMenu =newQMenu(ui->stuTableWidget);
3action =newQAction("Copy",this);

setContextMenuPolicy方法用来设置widget菜单项的显示方法,而CustomContextMenu是唯一与邮件菜单有关的参数,因此这里我们将菜单显示方法设置为该类型。如果widget设置为CustomContextMenu时,当在数据上点击右键时就会发送customContextMenuRequested ( const QPoint & pos )信号,该信号还会捕捉到点击右键的位置,并用pos参数来存储。与此信号关联的槽函数我们定义如下:

1voidstudentInfo::on_stuTableWidget_customContextMenuRequested(QPoint pos)
2{
3    popMenu->addAction(action);
4    popMenu->exec(QCursor::pos());
5}

我们首先将菜单选项action添加到邮件弹出菜单popMenu中,再通过exec方法在pos()位置显示该邮件菜单,pos()返回的位置即为点击鼠标的位置。

现在,如果点击右键菜单选项并不会发生任何动作,这是因为我们并没有关联相应的槽函数。由于具体的菜单选项不同,其函数的实现也不同,这里我们只给出框架,如下:

1voidstudentInfo::rightClickedOperation()
2{
3    //do something
4}

定义好槽函数,最关键的是与相应的信号连接。对于上述两个槽函数,我们可以使用两种方法进行信号和槽的关联:在Qt Desinger模式下添加或手动进行connect关联。对于customContextMenuRequested信号,我们使用前种方法实现信号和槽的关联;对于右键菜单选项的功能实现,我们可以通过connect函数实现,如下:

1connect(action, SIGNAL(triggered()),this, SLOT(rightClickedOperation()));

要在QTableWidget实现右键菜单功能,可以使用QMenu和contextMenuEvent()事件。具体实现步骤如下: 1.创建QMenu对象并添加菜单项。 ```python menu = QMenu(self) menu.addAction("Copy") menu.addAction("Paste") ``` 2.在QTableWidget的contextMenuEvent()事件中,设置菜单的位置,并显示菜单。 ```python def contextMenuEvent(self, event): menu = QMenu(self) menu.addAction("Copy") menu.addAction("Paste") if self.itemAt(event.pos()): menu.exec_(event.globalPos()) ``` 完整代码如下: ```python from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QMenu from PyQt5.QtCore import Qt class MainWindow(QMainWindow): def __init__(self): super().__init__() self.table = QTableWidget(self) self.table.setRowCount(4) self.table.setColumnCount(2) self.table.setHorizontalHeaderLabels(["Name", "Age"]) self.table.setItem(0, 0, QTableWidgetItem("Tom")) self.table.setItem(0, 1, QTableWidgetItem("20")) self.table.setItem(1, 0, QTableWidgetItem("Jerry")) self.table.setItem(1, 1, QTableWidgetItem("18")) self.table.setItem(2, 0, QTableWidgetItem("Lucy")) self.table.setItem(2, 1, QTableWidgetItem("22")) self.table.setItem(3, 0, QTableWidgetItem("John")) self.table.setItem(3, 1, QTableWidgetItem("25")) self.setCentralWidget(self.table) def contextMenuEvent(self, event): menu = QMenu(self) menu.addAction("Copy") menu.addAction("Paste") if self.table.itemAt(event.pos()): menu.exec_(event.globalPos()) if __name__ == "__main__": app = QApplication([]) window = MainWindow() window.show() app.exec_() ``` 这样就可以在QTableWidget实现右键菜单功能了。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值