简体   繁体   中英

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

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. You then have to adapt your signal and slot ( leftclicked and self.lbl_clicked ) to accept and use the parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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