Brat Karamazov
Brat Karamazov

Reputation: 161

How to communicate between two widgets inside one QObject that is created in QMainWindow

I have problem regarding Signals and Slots in Qt. Let’s say I have three Classes, and methods in it as it is below (ignoring creation of GUI and some other things):

import sys
from PySide2.QtWidgets import *
from PySide2.QtCore import *


class MainWindow(QDialog):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.button1 = QPushButton("Create Car Control!")

        self.mdiArea = QMdiArea()

        layout = QVBoxLayout()
        layout.addWidget(self.mdiArea)
        layout.addWidget(self.button1)

        self.button1.clicked.connect(self.createCar)

        self.setLayout(layout)
        self.setWindowTitle("TEST!")

    def createCar(self):
        car1 = CarControl(self)
        tireWind = car1.getTireWind()
        self.mdiArea.addSubWindow(tireWind)
        tireWind.show()


class CarControl(QObject):

    def __init__(self, parent=None):
        super(CarControl, self).__init__()

        self.tire = TireWind(parent)
        self.tire.show()
        self.tire.empty_tire.connect(self.printProblem)

    def getTireWind(self):
        return self.tire

    @Slot(str)
    def printProblem(self, probl):
        print(probl)


class TireWind(QWidget):

    empty_tire = Signal(str)

    def __init__(self, parent=None):
        super(TireWind, self).__init__(parent)
        self.button_emptyTire = QPushButton("Empty Tire")
        self.button_emptyTire.clicked.connect(self.sendEmptyTireSignal)

        layout = QVBoxLayout()
        layout.addWidget(self.button_emptyTire)

        self.setLayout(layout)
        self.setWindowTitle("TIRE")

    def sendEmptyTireSignal(self):
        print("I'm in")
        self.empty_tire.emit("EMPTY TIRE")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

This is short version of code. In MainWindow I have mdiArea and I am creating object that controls everything that happens in Car Windows (CarControl) and I add its QWidget TireWind as subWindow in mdiArea. Thing is when I click on button_emptyTire in my subWindow TireWind it should emit signal empty_tire and my “controller” CarControl should recognize it and run method printProblem. But I’m not achieving it. How can I communicate between TireWind and CarControl? I'm having multiple QWidgets in CarControl so I was thinking managing all between its widgets inside CarControl

Hope it's enough of code to understand the problem :)

EDIT: I made a typo: It should be: self.tire.empty_tire.connect(self.printProblem) instead self.tire.sendEmptyTireSignal.connect(self.printProblem).

EDIT2: Edited code so it is runnable.

It still does not work! :(

Upvotes: 1

Views: 363

Answers (2)

SitiSchu
SitiSchu

Reputation: 1417

You're connecting a function to a Slot with this line:

self.tire.sendEmptyTireSignal.connect(self.printProblem)

instead it should read

self.tire.empty_tire.connect(self.printProblem)

because empty_tire is the signal you want to connect your slot to.

Edit:

With the new code what seems to be happening is that the Garbage collector is cleaning up your CarControl object. This causes your signal to be disconnected because the QObject doesn't exist anymore. You can fix this by putting it into a list for example:

class MainWindow(QDialog):
    cars = []

    def __init__(self, parent=None):
        ...

    def createCar(self):
        car1 = CarControl(self)
        # append it to the list so the object is still referenced
        self.cars.append(car1)
        tireWind = car1.getTireWind()
        self.mdiArea.addSubWindow(tireWind)

        tireWind.show()

Upvotes: 2

Brat Karamazov
Brat Karamazov

Reputation: 161

I found it. It was silly mistake.

instead of:

class CarControl(QObject):

def __init__(self, parent=None):
    super(CarControl, self).__init__()

it should go:

class CarControl(QObject):

def __init__(self, parent=None):
    super(CarControl, self).__init__(parent)

I wasn’t passing parent to QObject, so it probably couldn't reference anywhere or something like that. so yeah, that's it.

Upvotes: 0

Related Questions