我应该提一下,我已经阅读了这些内容,但我仍然无法实现我的目标:
[ Using a dictionary in a for loop to create buttons doesn't work
[ QtCore.QObject.connect in a loop only affects the last instance
我的目标是制作一个 Linux“启动器”应用程序。按钮的创建、放置等工作非常顺利,但存在一个问题 - 所有按钮触发相同的回调 - 最后一个在按钮创建循环中连接。
这是脚本的基本版本,用于说明我正在尝试做的事情:
class App(QMainWindow):
def launch(self, filepath):
subprocess.run(filepath)
def __init__(self):
super(App, self).__init__()
for btn in matrix:
filepath = matrix[btn]['path']
icon = matrix[btn]['setIcon']
posx = matrix[btn]['posx']
posy = matrix[btn]['posy']
matrix[btn] = QToolButton(self)
matrix[btn].setIcon(QIcon(icon))
matrix[btn].setIconSize(QSize(64, 64))
matrix[btn].resize(100, 100)
matrix[btn].move(posx, posy)
matrix[btn].clicked.connect(lambda launch: self.launch(filepath))
self.initUI()
def initUI(self):
self.setGeometry(150, 150, 1250, 650)
self.setWindowTitle('LinuxLauncher')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
我知道有答案,但我已经研究了几个小时 - 如果有人能帮我解决这个问题,我将不胜感激 - 谢谢!
最佳答案
我不明白矩阵是什么类型的结构,但我认为它相当于一个字典列表。
问题是您必须将参数作为参数传递给分配它的 lambda 函数,点击信号将一个 bool 值作为参数,指示按钮是否被选中(默认情况下此属性被禁用,因此此值为 false),您必须添加另一个参数。
class App(QMainWindow):
def launch(self, filepath):
subprocess.run(filepath)
def __init__(self):
super(App, self).__init__()
matrix = [{"path": "path1", "setIcon": "icon1", "posx": 0, "posy": 0},
{"path": "path2", "setIcon": "icon2", "posx": 0, "posy": 150},
{"path": "path3", "setIcon": "icon3", "posx": 0, "posy": 300}]
for value in matrix:
filepath = value['path']
icon = value['setIcon']
posx = value['posx']
posy = value['posy']
btn = QToolButton(self)
btn.setIcon(QIcon(icon))
btn.setIconSize(QSize(64, 64))
btn.resize(100, 100)
btn.move(posx, posy)
btn.clicked.connect(lambda checked, arg=filepath: self.launch(arg))
self.initUI()
def initUI(self):
self.setGeometry(150, 150, 1250, 650)
self.setWindowTitle('LinuxLauncher')
self.show()
关于python - 在循环中创建 PyQt5 按钮 : all buttons trigger the same callback,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49184163/