当我在QTableWidget上单击鼠标右键时,我试图显示QMenu。问题在于,只要出现菜单,它就会显示为一个点。在下面,您可以找到一个最小的可复制示例。
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import (QApplication, QAction, QMenu, QTableWidget,
QAbstractItemView)
class PhotoSetTable(QTableWidget):
_menu = None
def __init__(self, parent=None):
super().__init__(parent)
self.setRowCount(0)
self.setColumnCount(2)
self.setHorizontalHeaderLabels(["Name", "Count"])
self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self._menu = self._generate_menu()
row_position = self.rowCount()
self.insertRow(row_position)
name_item = QtWidgets.QTableWidgetItem("asd")
name_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
count_item = QtWidgets.QTableWidgetItem("0")
count_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.setItem(row_position, 0, name_item)
self.setItem(row_position, 1, count_item)
#self._refresh()
@staticmethod
def _generate_menu():
menu = QMenu()
menu.addAction(QAction("Quit"))
menu.addSeparator()
menu.addAction(QAction("WUUU"))
menu.addSeparator()
return menu
def mousePressEvent(self, e):
super().mousePressEvent(e)
if e.buttons() == QtCore.Qt.RightButton:
item = self.itemAt(e.pos())
if item is not None:
self._menu.exec(e.globalPos())
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = PhotoSetTable()
ex.show()
sys.exit(app.exec_())
是什么原因导致这种行为?
答案 0 :(得分:2)
问题在于将QAction
添加到生成的上下文菜单中。相反,请尝试添加菜单项,其中以菜单项名称作为字符串作为第一个参数,然后将其作为第二个参数调用。
@staticmethod
def _generate_menu():
menu = QMenu()
menu.addAction("Quit", lambda: print('quitting'))
menu.addSeparator()
menu.addAction("WUUU", method_name)
menu.addSeparator()
return menu
答案 1 :(得分:0)
之所以只看到一个“点”,是因为您实际上是在创建一个没有父级的QAction,因此实际上看到的是一个空菜单。
QMenu.addAction(QAction*)
不会将QAction的所有权转让给菜单(如here所述,它的行为为QWidget.addAction
,因为QMenu是QWidget的后代),这意味着一旦{{1} }方法返回时,这些操作将“转移”到Python的垃圾收集器(又名已删除)。
如果出于任何原因,您确实需要创建“独立” QAction,请为其添加父项(或使它们成为某个持久对象的属性,甚至可以通过添加到另一个持久对象(例如列表或元组)) ,或仅使用MalloyDelacroix指出的_generate_menu()
。
顺便说一句,如果您仅将菜单设置为父菜单,就足够了:
menu.addAction(str)
也就是说,至少根据您的示例,确实不需要为此使用静态方法。