将数据从子级发送到PyQt5的父窗口

时间:2019-04-24 13:59:08

标签: python pyqt

我不能做的事

我无法将数据从孩子发送回父窗口。

我有什么

我有一个复杂的GUI,其中包含多个将数据发送到子窗口的窗口。每个窗口在同一目录中代表一个唯一的Python脚本。由于通信始终是单向的(父母对孩子),因此无需明确指定父母和孩子。但是,由于每个窗口(即每个类)都有自己的文件,所以现在我需要将数据从孩子发送回父母,并且无法弄清楚该如何做。

示例

这是一个最小的示例,显示了我要完成的工作的基础。 它的作用:win01打开win02win02触发func中的win01

# testfile01.py

import sys
from PyQt5.QtWidgets import *
import testfile02 as t02

class win01(QWidget):

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

        self.win02 = t02.win02()
        self.button = QPushButton("open win02", self)
        self.button.move(100, 100)
        self.button.clicked.connect(self.show_t02)

    def initUI(self):
        self.center

    def show_t02(self):
        self.win02.show()

    def func(self):
        print("yes!")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = win01()
    ex.show()
    sys.exit(app.exec_())

##########################################################################

# testfile02.py

from PyQt5.QtWidgets import *
import testfile01 as t01

class win02(QWidget):

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

        self.win01 = t01.win01()
        self.button = QPushButton()
        self.button.clicked.connect(self.win01.func)

    def initUI(self):
        self.center()

我尝试过的

在第二个窗口中导入testfile01总是会导致错误: RecursionError: maximum recursion depth exceeded.

然后,我尝试了以下方法,但它们也不起作用:

  • 不导入win02中的testfile01并将parent=None调整为其他不同的对象
  • __init__的{​​{1}}调用中导入testfile01
  • win02中创建一个信号来触发win02中的func

问题

有没有解决方法,如何正确触发win01的{​​{1}}中的func

2 个答案:

答案 0 :(得分:2)

为什么会出现 RecursionError:超过最大递归深度

之所以得到它,是因为您有一个循环导入,该循环生成了一个无限循环,在testfile01中,您正在导入文件testfile02,而在testfile02中,您正在导入testfile01,...。因此,这表明设计不良。


Qt为对象提供了与其他对象进行信息传递的信号机制,这具有类之间不依赖的优势,这是一个长期的巨大好处(例如,避免了循环导入),因此我认为这是最合适的原因。

为此,我将在类win02中创建点击信号,该点击信号将由按钮的点击信号触发,并使该点击信号称为func:

testfile01.py

import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication
import testfile02 as t02


class win01(QWidget):
    def __init__(self, parent=None):
        super(win01, self).__init__(parent)

        self.win02 = t02.win02()
        self.win02.clicked.connect(self.func)
        self.button = QPushButton("open win02", self)
        self.button.move(100, 100)
        self.button.clicked.connect(self.show_t02)

    def show_t02(self):
        self.win02.show()

    def func(self):
        print("yes!")


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

testfile02.py

from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout


class win02(QWidget):
    clicked = pyqtSignal()

    def __init__(self, parent=None):
        super(win02, self).__init__(parent)
        self.button = QPushButton("call to func")
        self.button.clicked.connect(self.clicked)
        lay = QVBoxLayout(self)
        lay.addWidget(self.button)

我建议您阅读:

答案 1 :(得分:1)

这两个小部件都是独立的,并且两者之间没有链接。 将win02设置为win02的父级。

在win01课堂上
替换:

self.win01 = t02.win02()
#and
self.win02.show()

具有:

self.win01 = t02.win02(self)
#and
self.win01.show()

和在win02中的类
替换:

self.win02 = t01.win01()
#and
self.button.clicked.connect(self.win01.func)

具有:

self.win02 = self.parent()
#and
self.button.clicked.connect(self.win02.func)