简体   繁体   English

如何在 Pyqt5 中动态创建 Widget 并分配信号?

[英]How to create Widgets dynamically and assign signals in Pyqt5?

My Intention is to create a label dynamically and assign some functions/signals to that label.我的意图是动态创建一个标签并将一些功能/信号分配给该标签。 Successfully complete the first part of my intention, but struck to assign signals to that label.成功完成了我的意图的第一部分,但我很想给那个标签分配信号。 For Example, if I Click "Accounts " or " kannaku" or "F1" , then I Need to print " You clicked label1" and so on例如,如果我点击“Accounts ”或“ kannaku”“F1” ,那么我需要打印“ You clicked label1”等等

import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import assist_stylesheet_001

dict_lbl = {
    "lbl1":{"name":"label1","item1":"Accounts",   "item2":"kannagu",    "shortcut":"F1","printitem":"You clicked label1"},
    "lbl2":{"name":"label2","item1":"Inventory",  "item2":"Saragu",     "shortcut":"F2","printitem":"You clicked label2"},
    "lbl3":{"name":"label3","item1":"Manufacture","item2":"Thayarippu", "shortcut":"F3","printitem":"You clicked label3"},
    "lbl4":{"name":"label4","item1":"PayRoll",    "item2":"Sambalam",   "shortcut":"F4","printitem":"You clicked label4"}
}

dict_key = {k: {n: d[k] for n, d in dict_lbl.items()} for k in {k for d in dict_lbl.values() for k in d}}
sub_keys = list(set().union(*[d.keys() for d in dict_lbl.values()]))


class MyLabel(QLabel):
    leftclicked = pyqtSignal()
    entery = pyqtSignal()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.leftclicked.emit()
        QLabel.mousePressEvent(self, event)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter:
            self.entery.emit()
        QLabel.keyPressEvent(self,event)

class Dynamic_Widgets(QWidget):
    def __init__(self):
        super(). __init__()
        self.setWindowTitle("Dynamic Widget")
        self.vbox1,self.vbox2,self.vbox3,self.hbox = QVBoxLayout(),QVBoxLayout(),QVBoxLayout(),QHBoxLayout()

        self.hbox.addLayout(self.vbox1),self.hbox.addLayout(self.vbox2),self.hbox.addLayout(self.vbox3)
        self.hbox.addSpacing(5)
        self.setLayout(self.hbox)

        self.name,self.itm1,self.itm2,self.scut,self.pitm = {}, {}, {}, {}, {}

        for ikey,ivalue in dict_key['item1'].items():
            self.itm1[ikey] = MyLabel()
            self.itm1[ikey].setObjectName("obj"+ivalue)
            self.itm1[ikey].setProperty("type","1")
            self.itm1[ikey].setStyleSheet(assist_stylesheet_001.style_toplayout())
            self.itm1[ikey].leftclicked.connect(self.lbl_clicked)
            self.itm1[ikey].setText(str(ivalue))
            self.vbox1.addWidget((self.itm1[ikey]))
            print(ikey,ivalue)

        for ikey, ivalue in dict_key['item2'].items():
            self.itm2[ikey] = MyLabel()
            self.itm2[ikey].setObjectName("obj"+ivalue)
            self.itm2[ikey].setProperty("type", "1")
            self.itm2[ikey].setStyleSheet(assist_stylesheet_001.style_toplayout())
            self.itm2[ikey].leftclicked.connect(self.lbl_clicked)
            self.itm2[ikey].setText(str(ivalue))
            self.vbox2.addWidget((self.itm2[ikey]))

        for ikey, ivalue in dict_key['shortcut'].items():
            self.scut[ikey] = MyLabel()
            self.scut[ikey].setObjectName("obj"+ivalue)
            self.scut[ikey].setProperty("type", "1")
            self.scut[ikey].setStyleSheet(assist_stylesheet_001.style_toplayout())
            self.scut[ikey].leftclicked.connect(self.lbl_clicked)
            self.scut[ikey].setText(str(ivalue))
            self.vbox3.addWidget((self.scut[ikey]))


    def lbl_clicked(self):
        print("dd")


def main():
    app = QApplication(sys.argv)
    ex = Dynamic_Widgets()
    qApp.setStyleSheet(assist_stylesheet_001.style_toplayout())
    ex.show()
    sys.exit(app.exec_())
    
if __name__ == '__main__':
    main()

If I understand your intention correctly, you need to pass the value of each item, which you want printed by the function, as a named parameter of the label.如果我正确理解您的意图,您需要将希望由函数打印的每个项目的值作为标签的命名参数传递。 Like so:像这样:

 for ikey,ivalue in dict_key['item1'].items():
                self.itm1[ikey] = MyLabel()
                self.itm1[ikey].setObjectName("obj"+ivalue)
                [...]
                self.itm1[ikey].leftclicked.connect(lambda clicked=True a=ikey: self.lbl_clicked(a))

This makes sure, that ikey will not get stuck in the for-loop, but will be bound to the value it had at the time the lambda was created.这可以确保ikey不会卡在 for 循环中,而是绑定到它在创建 lambda 时所具有的值。 You then have to adapt your signal and slot ( leftclicked and self.lbl_clicked ) to accept and use the parameter.然后,您必须调整您的信号和插槽( leftclickedself.lbl_clicked )以接受和使用该参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM