как передать данные между двумя несвязанными виджетами

Есть 2 виджета, каждый из которых определен в отдельном файле. Эти виджеты создаются в стеке главного окна (тоже отдельный файл).

В одном из виджетов есть кнопка, по нажатию на которую открывается диалоговое окно, пользователь вводит данные и они по сигналу передаются в этот виджет с кнопкой.

Как теперь я могу передать данные из этого виджета в другой, минуя главное окно?

Первый виджет:

class Form1(QWidget):
  def __init__(self):
    super(Form1, self).__init__()
    self.setWindowTitle('Form1')
    hbox1 = QHBoxLayout()
    hbox1.addWidget(QLabel("form1"))

    add_btn = QPushButton("Add data")
    add_btn.clicked.connect(self.add)
    hbox1.addWidget(add_btn)
    self.setLayout(hbox1)

  def add(self):
    self.dialog = UserDialog()
    self.dialog.signal.connect(self.signal_handler)
    self.dialog.show()

  def signal_handler(self, data):
    self.data = data
    print(data)

Второй виджет:

class Form2(QWidget):
  def __init__(self):
    super(Form2, self).__init__()
    self.setWindowTitle('Form2')
    hbox2 = QHBoxLayout()
    hbox2.addWidget(QLabel("form2"))
    self.setLayout(hbox2)

    self.data = 0

Диалоговое окно (с которого передаются данные в первый виджет):

class UserDialog(QDialog):
  signal = pyqtSignal(float)
  def __init__(self):
    super(UserDialog, self).__init__()

    vbox = QVBoxLayout(self)
    form = QFormLayout()
    self.data = QDoubleSpinBox()
    form.addRow("Data", self.data)

    buttonbox = QDialogButtonBox(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
    buttonbox.accepted.connect(self.accept)
    buttonbox.rejected.connect(self.reject)

    vbox.addLayout(form)
    vbox.addWidget(buttonbox)

  def accept(self):
    self.signal.emit(self.data.value())
    super().accept()

Главное окно, в котором эти виджеты расположены:

class Main(QWidget):
  def __init__(self):
    super(Main, self).__init__()

    self.leftlist = QListWidget ()
    self.leftlist.insertItem (0, 'form1' )
    self.leftlist.insertItem (1, 'form2' )

    self.stack1 = Form1()
    self.stack2 = Form2()

    self.Stack = QStackedWidget (self)
    self.Stack.addWidget (self.stack1)
    self.Stack.addWidget (self.stack2)


    hbox = QHBoxLayout(self)
    hbox.addWidget(self.leftlist)
    hbox.addWidget(self.Stack)

    self.leftlist.currentRowChanged.connect(self.display)
    self.setWindowTitle('StackedWidget demo')
    self.show()

 def display(self,i):
   self.Stack.setCurrentIndex(i)


if __name__ == '__main__':
  app = QApplication(sys.argv)
  main = Main()
  sys.exit(app.exec_())

Теперь нужно передать данные во второй виджет. Как это сделать?


Ответы (1 шт):

Автор решения: S. Nick

Как вариант:

main_w.py

import sys
from PyQt5.Qt import *

from wi_1 import Form1                                             # +++
from wi_2 import Form2                                             # +++

class Main(QWidget):
    def __init__(self):
        super(Main, self).__init__()

        self.data = None                                           # +++

        self.leftlist = QListWidget ()
        self.leftlist.insertItem (0, 'form1' )
        self.leftlist.insertItem (1, 'form2' )

        self.stack1 = Form1()

        self.stack1.dialog.signal.connect(self.update_data)        # +++ <<<---

        self.stack2 = Form2()

        self.Stack = QStackedWidget (self)
        self.Stack.addWidget (self.stack1)
        self.Stack.addWidget (self.stack2)

        hbox = QHBoxLayout(self)
        hbox.addWidget(self.leftlist)
        hbox.addWidget(self.Stack)

        self.leftlist.currentRowChanged.connect(self.display)
        self.setWindowTitle('StackedWidget demo')
        self.show()

    def display(self,i):
       self.Stack.setCurrentIndex(i)

    def update_data(self, data):                                     # +++ <<<---
         self.data = data
         print(f'Main: {data}')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = Main()
    sys.exit(app.exec_())

wi_1.py

from PyQt5.Qt import *
from dw import UserDialog


class Form1(QWidget):
    def __init__(self):
        super(Form1, self).__init__()

        self.data = None                                               # +++

        self.setWindowTitle('Form1')
        hbox1 = QHBoxLayout()
        hbox1.addWidget(QLabel("form1"))

        add_btn = QPushButton("Add data")
        add_btn.clicked.connect(self.add)
        hbox1.addWidget(add_btn)
        self.setLayout(hbox1)

        self.dialog = UserDialog()                                     # +++
        self.dialog.signal.connect(self.signal_handler)                # +++

    def add(self):
#       self.dialog = UserDialog()                            
#       self.dialog.signal.connect(self.signal_handler)
       self.dialog.show()

    def signal_handler(self, data):
         self.data = data
         print(data)

wi_2.py

from PyQt5.Qt import *

class Form2(QWidget):
    def __init__(self):
        super(Form2, self).__init__()

        self.setWindowTitle('Form2')
        hbox2 = QHBoxLayout()
        hbox2.addWidget(QLabel("form2"))
        self.setLayout(hbox2)

        self.data = 0

dw.py

from PyQt5.Qt import *

class UserDialog(QDialog):
    signal = pyqtSignal(float)

    def __init__(self):
        super(UserDialog, self).__init__()

        vbox = QVBoxLayout(self)
        form = QFormLayout()
        self.data = QDoubleSpinBox()
        form.addRow("Data", self.data)

        buttonbox = QDialogButtonBox(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        buttonbox.accepted.connect(self.accept)
        buttonbox.rejected.connect(self.reject)

        vbox.addLayout(form)
        vbox.addWidget(buttonbox)

    def accept(self):
        self.signal.emit(self.data.value())
        super().accept()

введите сюда описание изображения

→ Ссылка