PyQt5 循环构建菜单
PyQt5 Build Menus in a Loop
我有以下在 PyQt5 中在按钮上构建菜单的示例。虽然这很有效,但是当您要构建数百个菜单时,它会很麻烦。有没有办法在 for 循环中执行此操作?
inputMenu_0 = QMenu()
inputMenu_0.triggered.connect(lambda x: self.inputPb_0.setText(x.text()))
self.add_menu(self.inputs, inputMenu_0)
self.inputPb_0.setMenu(inputMenu_0)
使用上述代码段的工作示例。
#!/usr/bin/python3
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QMenu, QWidget
from PyQt5.QtGui import QIcon
class Window(QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
self.setWindowTitle("PyQT5 Minimal!")
self.central_widget = QWidget(self)
self.central_widget.setFocus()
self.setCentralWidget(self.central_widget)
self.inputPb_0 = QPushButton('Button 0', self)
self.inputPb_0.move(15, 10)
self.inputPb_1 = QPushButton('Button 1', self)
self.inputPb_1.move(15, 40)
self.inputs = [{'Homing':['X Home', 'Y Home', 'Z Home']},
{'Jog':['Jog A', 'Jog B', 'Jog C', 'Jog U', 'Jog V', 'Jog W', 'Jog X', 'Jog Y', 'Jog Z']},
{'Coolant':['Flood', 'Mist']},
{'Digital':['Digital 0', 'Digital 1', 'Digital 2', 'Digital 3']}
]
inputMenu_0 = QMenu()
inputMenu_0.triggered.connect(lambda x: self.inputPb_0.setText(x.text()))
self.add_menu(self.inputs, inputMenu_0)
self.inputPb_0.setMenu(inputMenu_0)
inputMenu_1 = QMenu()
inputMenu_1.triggered.connect(lambda x: self.inputPb_1.setText(x.text()))
self.add_menu(self.inputs, inputMenu_1)
self.inputPb_1.setMenu(inputMenu_1)
self.show()
def add_menu(self, data, menu_obj):
if isinstance(data, dict):
for k, v in data.items():
sub_menu = QMenu(k, menu_obj)
menu_obj.addMenu(sub_menu)
self.add_menu(v, sub_menu)
elif isinstance(data, list):
for element in data:
self.add_menu(element, menu_obj)
else:
action = menu_obj.addAction(data)
action.setIconVisibleInMenu(False)
if __name__ == '__main__':
app = QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
此代码将 运行 但两个按钮的连接都会转到第二个。如果您 select 按钮 0 中的菜单项,按钮 1 中的文本会发生变化。
self.inputMenu_0 = QMenu()
self.inputMenu_1 = QMenu()
for i in range(2):
getattr(self, 'inputMenu_' + str(i)).triggered.connect(lambda x: getattr(self, 'inputPb_' + str(i)).setText(x.text()))
self.add_menu(self.inputs, getattr(self, 'inputMenu_' + str(i)))
getattr(self, 'inputPb_' + str(i)).setMenu(getattr(self, 'inputMenu_' + str(i)))
以下代码片段有效,但我不知道如何在循环中编写连接代码。
self.inputMenu_0 = QMenu()
self.inputMenu_0.triggered.connect(lambda x: self.inputPb_0.setText(x.text()))
self.inputMenu_1 = QMenu()
self.inputMenu_1.triggered.connect(lambda x: self.inputPb_1.setText(x.text()))
for i in range(2):
#getattr(self, 'inputMenu_' + str(i)).triggered.connect(lambda x: getattr(self, 'inputPb_' + str(i)).setText(x.text()))
self.add_menu(self.inputs, getattr(self, 'inputMenu_' + str(i)))
getattr(self, 'inputPb_' + str(i)).setMenu(getattr(self, 'inputMenu_' + str(i)))
为避免这些混淆,最好限制 getattr 的使用,这样我们将保留更具可读性的代码,从而减少混淆。
for i in range(2):
button = getattr(self, "inputPb_{}".format(i))
menu = QMenu()
menu.triggered.connect(lambda action, button=button: button.setText(action.text()))
self.add_menu(self.inputs, menu)
button.setMenu(menu)
我有以下在 PyQt5 中在按钮上构建菜单的示例。虽然这很有效,但是当您要构建数百个菜单时,它会很麻烦。有没有办法在 for 循环中执行此操作?
inputMenu_0 = QMenu()
inputMenu_0.triggered.connect(lambda x: self.inputPb_0.setText(x.text()))
self.add_menu(self.inputs, inputMenu_0)
self.inputPb_0.setMenu(inputMenu_0)
使用上述代码段的工作示例。
#!/usr/bin/python3
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QMenu, QWidget
from PyQt5.QtGui import QIcon
class Window(QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
self.setWindowTitle("PyQT5 Minimal!")
self.central_widget = QWidget(self)
self.central_widget.setFocus()
self.setCentralWidget(self.central_widget)
self.inputPb_0 = QPushButton('Button 0', self)
self.inputPb_0.move(15, 10)
self.inputPb_1 = QPushButton('Button 1', self)
self.inputPb_1.move(15, 40)
self.inputs = [{'Homing':['X Home', 'Y Home', 'Z Home']},
{'Jog':['Jog A', 'Jog B', 'Jog C', 'Jog U', 'Jog V', 'Jog W', 'Jog X', 'Jog Y', 'Jog Z']},
{'Coolant':['Flood', 'Mist']},
{'Digital':['Digital 0', 'Digital 1', 'Digital 2', 'Digital 3']}
]
inputMenu_0 = QMenu()
inputMenu_0.triggered.connect(lambda x: self.inputPb_0.setText(x.text()))
self.add_menu(self.inputs, inputMenu_0)
self.inputPb_0.setMenu(inputMenu_0)
inputMenu_1 = QMenu()
inputMenu_1.triggered.connect(lambda x: self.inputPb_1.setText(x.text()))
self.add_menu(self.inputs, inputMenu_1)
self.inputPb_1.setMenu(inputMenu_1)
self.show()
def add_menu(self, data, menu_obj):
if isinstance(data, dict):
for k, v in data.items():
sub_menu = QMenu(k, menu_obj)
menu_obj.addMenu(sub_menu)
self.add_menu(v, sub_menu)
elif isinstance(data, list):
for element in data:
self.add_menu(element, menu_obj)
else:
action = menu_obj.addAction(data)
action.setIconVisibleInMenu(False)
if __name__ == '__main__':
app = QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
此代码将 运行 但两个按钮的连接都会转到第二个。如果您 select 按钮 0 中的菜单项,按钮 1 中的文本会发生变化。
self.inputMenu_0 = QMenu()
self.inputMenu_1 = QMenu()
for i in range(2):
getattr(self, 'inputMenu_' + str(i)).triggered.connect(lambda x: getattr(self, 'inputPb_' + str(i)).setText(x.text()))
self.add_menu(self.inputs, getattr(self, 'inputMenu_' + str(i)))
getattr(self, 'inputPb_' + str(i)).setMenu(getattr(self, 'inputMenu_' + str(i)))
以下代码片段有效,但我不知道如何在循环中编写连接代码。
self.inputMenu_0 = QMenu()
self.inputMenu_0.triggered.connect(lambda x: self.inputPb_0.setText(x.text()))
self.inputMenu_1 = QMenu()
self.inputMenu_1.triggered.connect(lambda x: self.inputPb_1.setText(x.text()))
for i in range(2):
#getattr(self, 'inputMenu_' + str(i)).triggered.connect(lambda x: getattr(self, 'inputPb_' + str(i)).setText(x.text()))
self.add_menu(self.inputs, getattr(self, 'inputMenu_' + str(i)))
getattr(self, 'inputPb_' + str(i)).setMenu(getattr(self, 'inputMenu_' + str(i)))
为避免这些混淆,最好限制 getattr 的使用,这样我们将保留更具可读性的代码,从而减少混淆。
for i in range(2):
button = getattr(self, "inputPb_{}".format(i))
menu = QMenu()
menu.triggered.connect(lambda action, button=button: button.setText(action.text()))
self.add_menu(self.inputs, menu)
button.setMenu(menu)