Отправка данных из дочернего окна в родительское окно в PyQt5 - PullRequest
2 голосов
/ 24 апреля 2019

Что я не могу сделать

Я не могу отправить данные обратно из дочернего окна в родительское окно.

Что у меня есть

У меня сложный графический интерфейс с несколькими окнами, отправляющими данные дочерним окнам. Каждое окно представляет собой уникальный Python-скрипт в одном и том же каталоге. Не было необходимости явно указывать родителей и детей, поскольку общение всегда было однонаправленным (от родителей к ребенку). Однако теперь мне нужно отправить данные от childs к родителям и не могу понять, как это сделать, поскольку каждое окно (то есть каждый класс) имеет свой собственный файл.

Пример

Вот минимальный пример, показывающий основу того, чего я хочу достичь. Что он делает: win01 открывает win02 и win02 запускает 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.

Затем я попробовал следующие подходы, но они тоже не сработали:

  • Не импортировать testfile01 в win02 и настраивать parent=None для других объектов
  • Импорт testfile01 в __init__ вызове win02
  • Создание сигнала в win02 для запуска func в win01

Вопрос

Есть ли решение, как правильно вызвать func в win01 из win02?

Ответы [ 2 ]

2 голосов
/ 24 апреля 2019

Почему вы получаете RecursionError: максимальная глубина рекурсии превышена ?

Вы получаете его, потому что у вас есть циклический импорт, который генерирует бесконечный цикл, в testfile01 вы импортируете файл testfile02, а в testfile02 вы импортируете testfile01, .... Так что это демонстрация плохого дизайна.


Qt предлагает механизм сигналов для объектов, чтобы передавать информацию другим объектам, и это имеет преимущество в том, что классы не зависят друг от друга, что является большим долгосрочным преимуществом (как, например, предотвращение циклического импорта), поэтому для этого причина, я думаю, что это наиболее уместно.

Для этого я создам сигнал clicked в классе win02, который будет запускаться сигналом clicked кнопки, и сделаю этот сигнал clicked вызовом 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 голос
/ 24 апреля 2019

Оба виджета независимы и не имеют никакой связи между ними.Установите win01 в качестве родительского элемента 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...