Pass signals between classes in PyQt
-
Hi, I am new to python and PyQt both, so stuck when trying to update my main screen when exiting an "exit screen".
I have two separate classes in my python file (code example typed below)
First Class = Main GUI with labels
I have a function in the first class (labelUpdate) to update the labels on my GUI to values in an INI file.Second Class = Edit Screen, to change values that will update Main Gui
I want to CALL the function (labelUpdate), even though I am in the second class, not the first class. I need to do this to update the values on the first/main GUI.I looked extensively at signals, but don't see how to use signals across different classes! Is that possible?
@class mainScreen(QtGui.QDialog, Ui_mainScreen):
def init(self, parent=None):
QtGui.QWidget.init(self, parent)
self.setupUi(self)#Reading to config and assigning the values to our txt labels self.labelUpdate() self.editWindow = None def labelUpdate(self): #NEED to run this when I hit OKAY on my edit screen! config = configparser.ConfigParser() config.read('netSettings.ini') #udating the labels from the config file for i in config.sections(): num = "%s" % i if num in config.sections(): print("Running Label UPDATE!", i) print("SElf", self) apiLabel = "self.apiLabel%s.setText(config[num]['api'])" % i exec(apiLabel) self.apiLabel1.setText(config[num]['api']) ipLabel = "self.ipLabel%s.setText(config[num]['ip address'])" % i exec(ipLabel) gatewayLabel = "self.gatewayLabel%s.setText(config[num]['gateway'])" % i exec(gatewayLabel)
#connecting out editscreen python file as a class
class editScreen(QtGui.QDialog, Ui_Dialog):
def init(self, parent=None):
QtGui.QDialog.init(self, parent)
self.setupUi(self)
self.editWindow = NoneokayButton = self.buttonBox.button(QtGui.QDialogButtonBox.Ok) okayButton.clicked.connect(self.okaySignal) def okaySignal(self): print("Saving Data to slot ", editButtonNumber) num = editButtonNumber config = configparser.ConfigParser() #Reading the file so we don't overwrite entire file with one entry config.read('netSettings.ini') config[num] = {'API': self.lineEditAPI.text(), 'IP ADDRESS': self.lineEditIP.text(), 'SUBNET MASK': self.lineEditMask.text(), 'GATEWAY': self.lineEditGateway.text(), 'DNS1': self.lineEditDNS1.text(), 'DNS2': self.lineEditDNS2.text() } configfile = open('netSettings.ini', 'w') config.write(configfile) configfile.close() #Done with file, closing it print("Closing Edit Window") #NEED to call labelupdate from right here.. not sure how to do with signals across classes! self.close()@
-
In C++ it is possible, it should be in python as well... However I am not sure on how you can do it... but from what I understand, you are calling the edit screen to show from your main window (no?) if so, you can connect (for example) @self.editWindow.nameOfSignal.connect(self.slotName) // not sure if is correct@
-
Actually, when I hit the "OK" Button on my edit dialog, I want the information on my Main screen to update with the new information. Since they are in separate classes, not sure how to communicate between classes.
Actually, I think I figured out how to do it, although not sure if it is the correct way to do it.
At the end of the okaySignal function in my editScreen class I added this after self.close():
@self.mainScreen = mainScreen(self)
self.mainScreen.close()
self.mainScreen.show()
self.mainScreen.labelUpdate()@This works.. I think it kept the old screen up, so closing and opening it works great, although since the labelUpdate() is already run at init, may not need the last line...
-
Well.. that doesn't work, just adds another screen on top of the old that has the correct info... Someone else finally pointed out the solution to me though, and I realize that I needed to post the full code, so it is available here: http://pastebin.com/GFHvrbeB
The issue is I call the edit window with:
@ def editButton(self, editButtonNum):
self.editWindow = None
global editButtonNumber
editButtonNumber = editButtonNum
if self.editWindow is None: #if Edit sceen not showing already
self.editWindow = editScreen(self) #Create out editwindow from our class editscreen
self.editWindow.show()@So I can still connect to it from there.
So I added the following line:
@ self.editWindow.updated.connect(self.labelUpdate)@
And then added two lines to editScreen():
@updated = QtCore.pyqtSignal()@ #Added right after class declaration@self.updated.emit()@ #Added right before self.close() in okaySignal()
Now everything works great.