在循环中创建 PyQt5 按钮:所有按钮触发相同的回调 [英] Creating PyQt5 buttons in a loop: all buttons trigger the same callback

查看:12
本文介绍了在循环中创建 PyQt5 按钮:所有按钮触发相同的回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我应该提到我已经阅读了这些,但我仍然无法实现我的目标:

I should mention that I've read these but I'm still unable to achieve my goal:

[在 for 循环中使用字典创建按钮不起作用

[QtCore.循环中的 QObject.connect 只影响最后一个实例

我的目标是制作一个 linux启动器"应用程序.按钮创建、放置等工作就像一个魅力,但有一个问题 - 所有按钮都会触发相同的回调 - 最后一个要在按钮创建循环中连接.

My goal is to make a linux 'launcher' application. Button creation, placement, etc. is working like a charm but there's one problem - all buttons trigger the same callback - the last one to be connected in the button creation loop.

这是一个基本版本的脚本来说明我正在尝试做的事情:

Here's a basic version of the script to illustrate what I'm trying to do:

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_())

我知道有一个答案,但我已经解决了几个小时 - 我很感激有人能帮助我摆脱困境 - 谢谢!

I know there's an answer but I've been at it for hours - I'd appreciate it someone could help me out of this jam - Thanks!

推荐答案

我不明白矩阵是什么类型的结构,但我认为它相当于一个字典列表.

I do not understand what type of structure is matrix, but I think it is equivalent to a list of dictionaries.

问题是您必须将其作为参数传递给分配它的 lambda 函数,clicked 信号将一个布尔值作为参数,指示按钮是否被选中(默认情况下,此属性被禁用,因此value 为 false),您必须添加另一个参数.

The problem is that you must pass as an argument to the lambda function assigning it, the clicked signal takes as a parameter a Boolean value that indicates that if the button is checked or not (by default this property is disabled so that this value is false), you must add another parameter.

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()

这篇关于在循环中创建 PyQt5 按钮:所有按钮触发相同的回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆