Reputation: 161
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
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
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