QPushButton binding does not work without lambda keyword
-
Hello,
i am facing a problem that i don't understand why it happen.When binding a QPushButton in a subclass method of my project
#! python3 # -*- coding: utf-8 -*- import sys import re from PySide2.QtWidgets import * from PySide2.QtCore import Qt, QRect, QCoreApplication from PySide2.QtGui import QIcon, QFont, QPixmap from FGIntMngtUI.FGIntMngtDeviceTab import Ui_FGIntMngtDeviceTab from FGIntMngtUI.FGIntMngtMCP23017Tab import Ui_FGIntMngtMCP23017Tab class FGIntMngtDevice(): def __init__(self, item: QTreeWidgetItem, objectTab: QTabWidget, displayLog: QTextEdit): self.item = item self.devicename = self.item.text(0) self.deviceid = self.item.text(1) self.deviceaddr = self.item.text(2) self.devicetype = self.item.text(3) self.objecttab = objectTab self.displaylog = displayLog self.devicetabValueSteelSheet = "QLabel { font-size:12pt; }" ##### ##### ##### ##### ##### ##### ##### ##### # Self String ##### ##### ##### ##### ##### ##### ##### ##### def __str__(self): return "Device Objects Managements (FGIntMngtDevice Class)" def updateDevice(self): self.displaylog.append("test") print("test") def getDevice(self): self.objecttab.clear() self.displaylog.append("Getting Device .... {}".format(type(self.objecttab))) self.displaylog.append("Device Name {}".format(self.devicename)) self.displaylog.append("Device Type {}".format(self.devicetype)) self.displaylog.append("Device Addr {}".format(self.deviceaddr)) self.currenttab = Ui_FGIntMngtDeviceTab() self.currenttab.setupUi(self.objecttab) self.currenttab.DeviceApplyBtn.clicked.connect(self.updateDevice) #self.currenttab.DeviceApplyBtn.clicked.connect(lambda: self.updateDevice()) self.currenttab.DeviceTypeValue.setStyleSheet(self.devicetabValueSteelSheet) self.currenttab.DeviceIdValue.setStyleSheet(self.devicetabValueSteelSheet) self.currenttab.DeviceIdValue.setText(self.deviceid) self.currenttab.DeviceAddrValue.setStyleSheet(self.devicetabValueSteelSheet) self.currenttab.DeviceAddrValue.setText(self.deviceaddr) self.currenttab.DeviceNameValue.setStyleSheet(self.devicetabValueSteelSheet) self.currenttab.DeviceNameValue.setText(self.devicename) index = self.currenttab.DeviceTypeValue.findText(self.devicetype, Qt.MatchFixedString) if index >= 0: self.currenttab.DeviceTypeValue.setCurrentIndex(index)
the line binding the button [ this does not work ]
self.currenttab.DeviceApplyBtn.clicked.connect(self.updateDevice)
but if i use the following code it work
self.currenttab.DeviceApplyBtn.clicked.connect(lambda: self.updateDevice())
I don't understand why i am oblige to use lambda here.
The main scripts create the GUI with a .py file create from a .ui file designed with Qt Designer.
The main scripts call some other class and ui classIf needed i can post more code
Regards
Daweed
-
Hi and welcome to devnet,
What version of PySide2 are you using ?
How did you install it ? -
Hello
I am using pyside2 5.13.0
and install it with the pip commandpip3 install PySide2
i am using python 3.7.2I am not sure that it's a pyside issue as if i am using for example the code to clear the displayLog widget [ QTextEdit object ] and no error are raised. The method updateDevice seems to just not be executed.
self.currenttab.DeviceApplyBtn.clicked.connect(self.displayLog.clear)
the binding work.
I am asking myself if there is not a problem when "propagating" the variable [ QTabWidget ]. I'm probably doing something wrong but I can not understand what :)
Here a view of the GUI
The main windows is create in the main script
#! python3 # -*- coding: utf-8 -*- import sys import re import socket from PySide2.QtWidgets import * from PySide2.QtCore import Qt, QRect, QCoreApplication from PySide2.QtGui import QIcon, QFont, QPixmap # FarmerSoft Tools Lib from FGIntMngt.FGIntMngtConfig import FGIntMngtConfig from FGIntMngt.FGIntMngtClient import FGIntMngtClient from FGIntMngt.FGIntMngtObject import FGIntMngtObject # FGIntMngt UI Windows & Widgets from FGIntMngtUI.FGIntMngtMain import Ui_MainWindow from FGIntMngtUI.About import Ui_About class MainWindow(QMainWindow, Ui_MainWindow): ##### ##### ##### ##### ##### ##### ##### MainWindow Constructor ##### ##### ##### ##### ##### ##### def __init__(self): super(MainWindow, self).__init__() ##### ##### ##### ##### ##### ##### ##### ##### ##### Main Windows Initialisation ##### ##### ##### ##### ##### ##### ##### ##### self.setupUi(self) ##### ##### ##### ##### ##### ##### ##### ##### ##### Properties ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### Steel Sheet ##### ##### ##### ##### ##### ##### ##### ##### self.LabelSteelSheet = "QLabel { font: bold; }" self.conSteelSheet = "QLabel { font: bold; color: green; }" self.disconSteelSheet = "QLabel { font: bold; color: red; }" ##### FGIntMngt Configuration self.fgintmngtconfig = FGIntMngtConfig() self.fgintmngtconfig.readConfig('treeobjects.ini') self.treeBranches = self.fgintmngtconfig.loadBranch(self.objectsTree) self.logDisplay.clear() ##### FGIntMngt Object Tree self.fgintmngtobjects = FGIntMngtObject(self.objectsTree, self.objectTab, self.logDisplay) ##### FGIntMngt TCP CLient self.fgintmngtclient = FGIntMngtClient() ##### Tab Module ##### ##### ##### ##### ##### ##### ##### ##### ##### Slots And Signals ##### ##### ##### ##### ##### ##### ##### ##### ##### Main Window ##### ##### Menu File self.actionQuit.triggered.connect(self.quitGui) ##### ##### Menu Configuration self.actionReadDevices.triggered.connect(self.readDevices) ##### ##### Menu Help self.actionAbout.triggered.connect(self.showAbout) ##### Status Frame Binding self.connexionButton.clicked.connect(self.connectFGIntSrv) ##### Tree Frame Binding self.objectsTree.itemClicked.connect(self.fgintmngtobjects.getObject) def quitGui(self): self.fgintmngtclient.setConnStatus(0) self.close() def showAbout(self): ##### About UI self.about = QWidget() self.ui_about = Ui_About() self.ui_about.setupUi(self.about) self.about.show() def connectFGIntSrv(self): self.logDisplay.clear() self.logDisplay.append("Connexion Parameters : {}:{}".format(self.fgintmngtclient.getFGIntHost(), self.fgintmngtclient.getFGIntPort())) if self.fgintmngtclient.getConnStatus() == 0: self.logDisplay.append("ready to connect") if self.fgintmngtclient.connectServer() == 1: self.logDisplay.append("Connection OK") self.connstatusValue.setText('Connected') self.connstatusValue.setStyleSheet(self.conSteelSheet) self.connexionButton.setText('Disconnect') data = self.fgintmngtclient.sock.recv(1024).decode("utf-8") self.logDisplay.append(data) self.readDevices() else: self.logDisplay.append("Connection Failed") self.fgintmngtclient.setConnStatus(0) self.connstatusValue.setText('Not Connected') self.connexionButton.setText('Connect') self.connstatusValue.setStyleSheet(self.disconSteelSheet) else: self.logDisplay.append("Disconnection") self.fgintmngtclient.setConnStatus(0) self.connstatusValue.setText('Not Connected') self.connexionButton.setText('Connect') self.connstatusValue.setStyleSheet(self.disconSteelSheet) self.fgintmngtclient.sendCmd("exit\n", 1024) def readDevices(self): self.logDisplay.clear() self.logDisplay.append("Nb d elements a purger : {}".format(self.treeBranches['Devices']['widget'].childCount())) if self.treeBranches['Devices']['widget'].childCount() > 0: self.logDisplay.append("Cleaning Devices Branch ...") for i in reversed(range(self.treeBranches['Devices']['widget'].childCount())): self.treeBranches['Devices']['widget'].removeChild(self.treeBranches['Devices']['widget'].child(i)) if self.fgintmngtclient.getConnStatus() == 1: self.logDisplay.append("Listing devices from FG interface ...") datatab = self.fgintmngtclient.sendCmd("show devices\n", 1024).splitlines() #self.logDisplay.append("datatab Type : {}".format(type(datatab))) #self.logDisplay.append("datatab Length: {}".format(len(datatab))) devicenum = 1 devices = datatab[0][1:-1].split(',') for device in devices: for deviceaddr in device.split(' '): if re.match("^\dx\d{2}$", deviceaddr[1:-1]): self.logDisplay.append("New Device Found : {} at address {} Type : {}".format('device' + str(devicenum).zfill(2), deviceaddr[1:-1], 'Device')) item = QTreeWidgetItem(self.treeBranches['Devices']['widget'], 0) item.setText(0, 'device' + str(devicenum).zfill(2)) item.setText(1, 'item' + str(devicenum).zfill(2)) item.setText(2, deviceaddr[1:-1]) item.setText(3, 'Device') item.setText(4, 'Unknow') devicenum += 1 else: self.logDisplay.append("Not Connected") ##### ##### ##### ##### ##### ##### ##### ##### ##### Main Application Definition & Execution ##### ##### ##### ##### ##### ##### ##### ##### def main(): app = QApplication(sys.argv) main_window = MainWindow() main_window.show() sys.exit(app.exec_()) if __name__ == "__main__": main()
When clicking on an item in the QTreeWidget, an object is creating with a FGIntMngtObject Class
self.objectsTree.itemClicked.connect(self.fgintmngtobjects.getObject)
The FGIntMngtObject Class
#! python3 # -*- coding: utf-8 -*- import sys from PySide2.QtWidgets import * from PySide2.QtCore import Qt, QRect, QCoreApplication from PySide2.QtGui import QIcon, QFont, QPixmap from FGIntMngt.FGIntMngtDevice import FGIntMngtDevice class FGIntMngtObject(): def __init__(self, treeWidget: QTreeWidget, objectTab: QTabWidget, displayLog: QTextEdit): super(FGIntMngtObject, self).__init__() self.treeWidget = treeWidget self.objecttab = objectTab self.displaylog = displayLog ##### ##### ##### ##### ##### ##### ##### ##### # Self String ##### ##### ##### ##### ##### ##### ##### ##### def __str__(self): return "FGIntMngtObject Class" ##### ##### ##### ##### ##### ##### ##### ##### # Class Methods ##### ##### ##### ##### ##### ##### ##### ##### def getObject(self): # Debug Printing # #print("Getting Object from Tree ...") #print("Current Item : {}".format(self.treeWidget.currentItem())) #print("Item have {} Column(s) and {} Child(s)".format(self.treeWidget.currentItem().columnCount(), self.treeWidget.currentItem().childCount())) # End Debug Printing # if self.treeWidget.indexOfTopLevelItem(self.treeWidget.currentItem().parent()) != -1: # Check if obj is not a top level branch #for c in range(self.treeWidget.currentItem().columnCount()): # print("Column {} Value {}".format(c, self.treeWidget.currentItem().text(c))) if self.treeWidget.currentItem().text(3) == 'Device': #devicename, deviceaddr, devicetype, objectTab element = FGIntMngtDevice( self.treeWidget.currentItem(), self.objecttab, self.displaylog ) print("Nom de l'élément : {}".format(element.devicename)) element.getDevice() def updObject(self): print("Updating Object ....")
And from that if the QTreeWiddgetItem is a 'Device' type a Device Object will be generated and the QTabWidget is populate via the FGIntMngtDevice Class
Hopping that will help
If needed , i can post UI python files
Regards
-
Can you rather post a minimal example that shows that behaviour ?