在 QAction 菜单项中存储附加数据 - python
store additional data in QAction menu item - python
我有一个通过 for 循环生成的动态 qmenu。我已将其分解为最基本的属性。我想知道的是,我是否可以创建一个自定义 QMenuItem 以便我可以在每个菜单项中存储一个实际对象?目前它只支持用作名称的字符串。
如何在菜单项中存储额外的 data/information?
我想像正常一样设置显示文本,然后在 for 循环中另外向每个项目添加一个 class 对象或某种数据。我在 for 循环中放置了伪代码,但它被注释掉了..
我以为我已经通过创建自定义 QAction 项并从 QAction 继承而接近了,但是在尝试使用它时似乎没有用...
class ActionObject( QtGui.QAction ):
def __init__( self, text="", parent=None ):
super( ActionObject, self ).__init__( parent )
self.data = None
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Imports
# ------------------------------------------------------------------------------
import sys
from PySide import QtGui, QtCore
class Person():
def __init__(self, name="", age=None):
self.name = name
self.age = age
# Main Widget
# ------------------------------------------------------------------------------
class ExampleWidget(QtGui.QWidget):
def __init__(self,):
super(ExampleWidget, self).__init__()
self.initUI()
def initUI(self):
# formatting
self.setWindowTitle("Example")
# context menu
self.main_menu = QtGui.QMenu()
self.sub_menu = QtGui.QMenu("Great")
self.main_menu.addMenu(self.sub_menu)
names = ["Joe","Kevin","Amy","Doug","Jenny"]
# sub-menu
for x in xrange(len(names)):
name = str(x) + " - " + names[x]
action = self.sub_menu.addAction( name )
# action.data = Person()
action.triggered.connect(self.menu_action)
# widgets
self.factionsList = QtGui.QListWidget()
# signal
self.factionsList.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.factionsList.customContextMenuRequested.connect(self.on_context_menu_factions)
# layout
self.mainLayout = QtGui.QGridLayout(self)
self.mainLayout.addWidget(self.factionsList, 1, 0)
self.show()
def menu_action(self):
print "testing"
def on_context_menu_factions(self, pos):
self.main_menu.exec_( QtGui.QCursor.pos() )
# Main
# ------------------------------------------------------------------------------
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
ex = ExampleWidget()
res = app.exec_()
sys.exit(res)
您可以简单地使用 setData 来设置数据,下面是一个工作示例,我更改了您的代码位
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Imports
# ------------------------------------------------------------------------------
import sys
from PySide import QtGui, QtCore
from functools import partial
class Person():
def __init__(self, name="", age=None):
self.name = name
self.age = age
def getName(self):
return self.name
# Main Widget
# ------------------------------------------------------------------------------
class ExampleWidget(QtGui.QWidget):
def __init__(self,):
super(ExampleWidget, self).__init__()
self.initUI()
def initUI(self):
# formatting
self.setWindowTitle("Example")
# context menu
self.main_menu = QtGui.QMenu()
self.sub_menu = QtGui.QMenu("Great")
self.main_menu.addMenu(self.sub_menu)
names = ["Joe","Kevin","Amy","Doug","Jenny"]
# sub-menu
for index, name in enumerate(names):
fancyName = "%s - %s" % (index, name)
action = self.sub_menu.addAction( fancyName )
action.setData(Person(name=name))
action.triggered.connect(partial(self.menu_action, action))
# widgets
self.factionsList = QtGui.QListWidget()
# signal
self.factionsList.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.factionsList.customContextMenuRequested.connect(self.on_context_menu_factions)
# layout
self.mainLayout = QtGui.QGridLayout(self)
self.mainLayout.addWidget(self.factionsList, 1, 0)
self.show()
def menu_action(self, item):
itmData = item.data()
print itmData.getName()
def on_context_menu_factions(self, pos):
self.main_menu.exec_( QtGui.QCursor.pos() )
# Main
# ------------------------------------------------------------------------------
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
ex = ExampleWidget()
res = app.exec_()
sys.exit(res)
当然正如 Achayan 回答的那样,您可以使用 QAction
的 setData()
来设置额外的数据,并使用 data()
来获取存储的数据。
不过,以上将解决您的问题,让我们看看扩展 QAction。 QWidget
、QMenu
基于、实现addAction
允许传递QAction
对象。
class ActionObject( QtGui.QAction ):
def __init__( self, text="", parent=None ):
super( ActionObject, self ).__init__(text, parent )
self.data = None
class ExampleWidget(QtGui.QWidget):
# ...[cut]...
def initUI(self):
# ...[cut]...
# sub-menu
for x in xrange(len(names)):
name = str(x) + " - " + names[x]
action = ActionObject(name, self.sub_menu)
action.data = Person()
action.triggered.connect(self.menu_action)
self.sub_menu.addAction(action)
父级已明确设置,因为它是 QWidget
的实现,而不是 QMenu
。
这就是 PyQt/Pyside 允许在几乎所有地方使用自定义对象的方式 - 无需使用猴子补丁。
我有一个通过 for 循环生成的动态 qmenu。我已将其分解为最基本的属性。我想知道的是,我是否可以创建一个自定义 QMenuItem 以便我可以在每个菜单项中存储一个实际对象?目前它只支持用作名称的字符串。
如何在菜单项中存储额外的 data/information?
我想像正常一样设置显示文本,然后在 for 循环中另外向每个项目添加一个 class 对象或某种数据。我在 for 循环中放置了伪代码,但它被注释掉了..
我以为我已经通过创建自定义 QAction 项并从 QAction 继承而接近了,但是在尝试使用它时似乎没有用...
class ActionObject( QtGui.QAction ):
def __init__( self, text="", parent=None ):
super( ActionObject, self ).__init__( parent )
self.data = None
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Imports
# ------------------------------------------------------------------------------
import sys
from PySide import QtGui, QtCore
class Person():
def __init__(self, name="", age=None):
self.name = name
self.age = age
# Main Widget
# ------------------------------------------------------------------------------
class ExampleWidget(QtGui.QWidget):
def __init__(self,):
super(ExampleWidget, self).__init__()
self.initUI()
def initUI(self):
# formatting
self.setWindowTitle("Example")
# context menu
self.main_menu = QtGui.QMenu()
self.sub_menu = QtGui.QMenu("Great")
self.main_menu.addMenu(self.sub_menu)
names = ["Joe","Kevin","Amy","Doug","Jenny"]
# sub-menu
for x in xrange(len(names)):
name = str(x) + " - " + names[x]
action = self.sub_menu.addAction( name )
# action.data = Person()
action.triggered.connect(self.menu_action)
# widgets
self.factionsList = QtGui.QListWidget()
# signal
self.factionsList.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.factionsList.customContextMenuRequested.connect(self.on_context_menu_factions)
# layout
self.mainLayout = QtGui.QGridLayout(self)
self.mainLayout.addWidget(self.factionsList, 1, 0)
self.show()
def menu_action(self):
print "testing"
def on_context_menu_factions(self, pos):
self.main_menu.exec_( QtGui.QCursor.pos() )
# Main
# ------------------------------------------------------------------------------
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
ex = ExampleWidget()
res = app.exec_()
sys.exit(res)
您可以简单地使用 setData 来设置数据,下面是一个工作示例,我更改了您的代码位
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Imports
# ------------------------------------------------------------------------------
import sys
from PySide import QtGui, QtCore
from functools import partial
class Person():
def __init__(self, name="", age=None):
self.name = name
self.age = age
def getName(self):
return self.name
# Main Widget
# ------------------------------------------------------------------------------
class ExampleWidget(QtGui.QWidget):
def __init__(self,):
super(ExampleWidget, self).__init__()
self.initUI()
def initUI(self):
# formatting
self.setWindowTitle("Example")
# context menu
self.main_menu = QtGui.QMenu()
self.sub_menu = QtGui.QMenu("Great")
self.main_menu.addMenu(self.sub_menu)
names = ["Joe","Kevin","Amy","Doug","Jenny"]
# sub-menu
for index, name in enumerate(names):
fancyName = "%s - %s" % (index, name)
action = self.sub_menu.addAction( fancyName )
action.setData(Person(name=name))
action.triggered.connect(partial(self.menu_action, action))
# widgets
self.factionsList = QtGui.QListWidget()
# signal
self.factionsList.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.factionsList.customContextMenuRequested.connect(self.on_context_menu_factions)
# layout
self.mainLayout = QtGui.QGridLayout(self)
self.mainLayout.addWidget(self.factionsList, 1, 0)
self.show()
def menu_action(self, item):
itmData = item.data()
print itmData.getName()
def on_context_menu_factions(self, pos):
self.main_menu.exec_( QtGui.QCursor.pos() )
# Main
# ------------------------------------------------------------------------------
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
ex = ExampleWidget()
res = app.exec_()
sys.exit(res)
当然正如 Achayan 回答的那样,您可以使用 QAction
的 setData()
来设置额外的数据,并使用 data()
来获取存储的数据。
不过,以上将解决您的问题,让我们看看扩展 QAction。 QWidget
、QMenu
基于、实现addAction
允许传递QAction
对象。
class ActionObject( QtGui.QAction ):
def __init__( self, text="", parent=None ):
super( ActionObject, self ).__init__(text, parent )
self.data = None
class ExampleWidget(QtGui.QWidget):
# ...[cut]...
def initUI(self):
# ...[cut]...
# sub-menu
for x in xrange(len(names)):
name = str(x) + " - " + names[x]
action = ActionObject(name, self.sub_menu)
action.data = Person()
action.triggered.connect(self.menu_action)
self.sub_menu.addAction(action)
父级已明确设置,因为它是 QWidget
的实现,而不是 QMenu
。
这就是 PyQt/Pyside 允许在几乎所有地方使用自定义对象的方式 - 无需使用猴子补丁。