参考资料:
Qt QWidget 添加右键菜单
QTableWidget 详解
编程中, 右键菜单是必不可少的, 特别是应用在 Table 类的控件上.
添加 Action
参考之前学 Qt 的系列笔记: 13、资源文件及 Action
Qt 中, 每个菜单项是一个 Action, 我们要显示右键菜单, 也要先定义好 Action, 方法就参考上面的笔记, 在 Qt 设计师中添加, 也可以像下面这样, 自己在代码中添加.
from PyQt4.QtGui import QMenu, QAction def on_open(): print u'打开' def on_download(): print u'下载' self.pop_menu = QMenu() self.action_open = QAction(self) self.action_open.setText(u"打开") self.action_open.triggered.connect(on_open) self.action_download = QAction(self) self.action_download.setText(u"下载") self.action_download.triggered.connect(on_download)
添加菜单
这里有两种方法, 一种是基于事件, 另一种是基于信号槽
重写事件
Qt 的控件都有一个右键菜单事件 contextMenuEvent
, 我们重写这个事件就可以了:
self.contextMenuEvent = self.e_contextMenuEvent def e_contextMenuEvent(self, event): self.pop_menu.clear() # 清除原有菜单 self.pop_menu.addAction(self.action_open) self.pop_menu.addSeparator() # 分隔线 self.pop_menu.addAction(self.action_download) self.pop_menu.exec_(event.globalPos()) event.accept()
如果想添加次级菜单, 可以使用 pop_menu.addMenu
:
def e_contextMenuEvent(self, event): self.pop_menu.clear() self.pop_menu.addAction(self.action_open) secondary_menu = self.pop_menu.addMenu(u'其它') secondary_menu.addAction(self.action_download) self.pop_menu.exec_(event.globalPos()) event.accept()
如果是在 Table 类的控件上, 你可以还需要得到当前鼠标所在的 item:
point = event.pos() item = self.tableWidgetItem.itemAt(point) if item != None: pass
要注意, itemAt
使用的是局部坐标, exec_
使用的是全局坐标.
关联信号槽
这种方法的机制是为控件建立 press 的信号槽, 在槽函数里判断是左键还是右键, 这种方法对有 item 的控件支持比较好, 如: QListWidget、QTableWidget、QTreeWidget.
以 QTableWidget 为例, 我们先在主窗体上拖一个 QTableWidget:
self.tableWidget.itemPressed.connect(self.on_item_clicked) # 关联信号槽 def on_item_clicked(self, item): if QtGui.qApp.mouseButtons() == QtCore.Qt.LeftButton: return elif QtGui.qApp.mouseButtons() == QtCore.Qt.RightButton: self.show_menu() def show_menu(self): self.pop_menu.clear() self.pop_menu.addAction(self.action_open) secondary_menu = self.pop_menu.addMenu(u'其它') secondary_menu.addAction(self.action_download) self.pop_menu.exec_(QtGui.QCursor.pos())
可以看到, 这种方法我们很方便的就得到了一个 item 对象, 而不需要像事件里那样使用 itemAt()
.
☠