如何在QMainWind中创建的一个QObject中的两个小部件之间进行通信

2024-10-03 06:32:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Qt中的信号和插槽有问题。假设我有三个类,其中的方法如下(忽略GUI的创建和其他一些事情):

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_())

这是代码的简短版本。在MainWindow中,我有mdiArea,我正在创建一个对象来控制车窗(CarControl)中发生的一切,并将其QWidgetTireWind添加为mdiArea中的子窗口。 当我在我的子窗口TireWind中单击button_emptyTire时,它应该发出信号empty_tire,而我的“控制器”CarControl应该识别它并运行方法printProblem。但我没有做到。 如何在TireWindCarControl之间进行通信? 我在CarControl中有多个qwidget,所以我想在CarControl中管理它的所有widget

希望有足够的代码来理解问题:)

编辑: 我打错了:应该是:self.tire.empty_tire.connect(self.printProblem),而不是self.tire.sendEmptyTireSignal.connect(self.printProblem)。你知道吗

编辑2: 编辑代码使其可运行。你知道吗

还是不行!:(


Tags: selfinitdefconnectbuttonemptyparentlayout
2条回答

我找到了。这是个愚蠢的错误。你知道吗

而不是:

class CarControl(QObject):

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

它应该是:

class CarControl(QObject):

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

我没有将父对象传递给QObject,所以它可能无法引用任何地方或类似的东西。 是的,就是这样。你知道吗

将函数连接到具有以下行的插槽:

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

相反,它应该是

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

因为empty_tire是您要将插槽连接到的信号。你知道吗

编辑:

在新代码中,垃圾收集器正在清理CarControl对象。这会导致您的信号断开,因为QObject已不存在。您可以通过放入列表来解决此问题,例如:

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

相关问题 更多 >