Qt World Summit: Submit your Presentation

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)

        #Reading to config and assigning the values to our txt labels
        self.editWindow = None
    def labelUpdate(self): #NEED to run this when I hit OKAY on my edit screen!
        config = configparser.ConfigParser()
        #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
                ipLabel = "self.ipLabel%s.setText(config[num]['ip address'])" % i
                gatewayLabel = "self.gatewayLabel%s.setText(config[num]['gateway'])" % i

    #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.editWindow = None

        okayButton = self.buttonBox.button(QtGui.QDialogButtonBox.Ok)
    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[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')
        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!

  • 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)

    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

    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.

Log in to reply