Probleme avec les Slot / QPushButton qui ne s'exécute pas sans mettre la fonction en 'lambda'
Bonjour,
Je suis en train d'essayer d'écrire une petite GUI pour contrôler et configurer une application python qui s'exécute sur Raspberry. Sans rentrer trop dans les détails il s'agit d'une interface matériel permettant de créer des panels réel [ pour créer un cockpit ] pour les avions du simulateur de vol Flightgear. L'interface et son code sont parfaitement fonctionnel, l'idée de l'interface graphique est de permettre la configuration des éléments de façon plus "friendly" afin que les fichiers de configuration de l'interface soit toujours bien structuré pour l'utilisateur lambda
L'interface est connecté dans le réseau local et comunique avec le simulateur en TCP/IP [ aucun problème de ce coté ]. La GUI se connecte dont également à l'interface via le réseau également, tous va bien jusque la. Ci dessous un screenshot de la GUI connecté à l'interface et ayant découvert un certains nombre d'éléments.
voilà pour le background.
https://i.imgur.com/RY1bQvsl.jpg
La GUI a été réalisé [ pour le coté graphique ] avec le QT Designer et les fichiers ui transformé en fichier python avec l utilitaire pyuic5, toujours aucun problème de ce coté la.
J ai donc un script principale
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
| #! python3
# -*- coding: utf-8 -*-
import sys
import re
import socket
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt, QRect, QCoreApplication
from PyQt5.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() |
J'ai donc un arbre dans lequel je retrouve mes éléments et que j ai connecté avec l'appel suivant
Code:
self.objectsTree.itemClicked.connect(self.fgintmngtobjects.getObject)
Jusque la tous fonctionne
L'appel a la fonction getObjet de la classe suivante se passe correctement
Class FGIntMngtObject
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #! python3
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt, QRect, QCoreApplication
from PyQt5.QtGui import QIcon, QFont, QPixmap
from FGIntMngt.FGIntMngtDevice import FGIntMngtDevice
class FGIntMngtObject():
def __init__(self, treeWidget: QTreeWidget, objectTab: QTabWidget, displayLog: QTextEdit):
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 ....") |
Le fait que l'élément soit un 'Device', déclenche la création d'un nouvel objet FGIntMngtDevice
Code:
1 2 3 4 5
| element = FGIntMngtDevice(
self.treeWidget.currentItem(),
self.objecttab,
self.displaylog,
) |
via la class suivante
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #! python3
# -*- coding: utf-8 -*-
import sys
import re
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt, QRect, QCoreApplication
from PyQt5.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")
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(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) |
Et c 'est la que j ai un problème
Lorsque je créé mon panel Tab (Qwidget dans un QTabWidget) et je veux connecter le bouton 'Apply' a une fonction locale de la classe, si je fait
Code:
self.currenttab.DeviceApplyBtn.clicked.connect(self.updateDevice)
cela ne fonctionne pas, mais ne renvoie aucune erreur non plus, la méthode ne semble tous simplement exécutée
alors que si je code comme ceci
Code:
self.currenttab.DeviceApplyBtn.clicked.connect(lambda: self.updateDevice())
cela fonctionne
Je ne comprends pas bien pourquoi.
J'ai cru comprendre au cours de mes lectures que ce n'était pas une bonne pratique d'uliser le 'lambda'
Ou ai je fais une erreur ?
Je peux poster les fichier python des interface graphique [ fichier .ui transformer en .py ] si nécéssaire.
D'avance merci
Daweed