Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved How to transfer data between two widgets if they can't get each other's instance directly

    Qt for Python
    4
    7
    1271
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Z
      Zac15 last edited by

      Hi guys,

      Looking at the code below, the widgetA and widgetB can communicate with each other because their instances can be accessed from mainwindow Class.

      But in my case, I am going to create extensions(widgetA and widgetB) from mainwindow , and the two sub widgets are in different project folders. I can't control how mainwindow initiates the two instances.

      In addition, widgetA and widgetB are not child widgets of mainwindow. So I cannot use findChild() to get instances from mainwindow.

      In such case, is there a way to make widgetA and widgetB transfer data by using signal/slot or other mechanism, if they can't get each other's instance?

      Cheers.

      from PyQt5 import QtCore, QtGui, QtWidgets
      
      
      class widgetB(QtWidgets.QWidget):
      
          procDone = QtCore.pyqtSignal(str)
      
          def __init__(self, parent=None):
              super(widgetB, self).__init__(parent)
      
              self.lineEdit = QtWidgets.QLineEdit(self)
              self.button = QtWidgets.QPushButton("Send Message to A", self)
              self.layout = QtWidgets.QHBoxLayout(self)
              self.layout.addWidget(self.lineEdit)
              self.layout.addWidget(self.button)
      
              self.button.clicked.connect(self.on_button_clicked)
      
          @QtCore.pyqtSlot()
          def on_button_clicked(self):
              self.procDone.emit(self.lineEdit.text())
      
          @QtCore.pyqtSlot(str)
          def on_procStart(self, message):
              self.lineEdit.setText("From A: " + message)
      
              self.raise_()
      
      
      class widgetA(QtWidgets.QWidget):
          procStart = QtCore.pyqtSignal(str)
      
          def __init__(self, parent=None):
              super(widgetA, self).__init__(parent)
      
              self.lineEdit = QtWidgets.QLineEdit(self)
              self.lineEdit.setText("Hello!")
      
              self.button = QtWidgets.QPushButton("Send Message to B", self)
              self.button.clicked.connect(self.on_button_clicked)
      
              self.layout = QtWidgets.QHBoxLayout(self)
              self.layout.addWidget(self.lineEdit)
              self.layout.addWidget(self.button)
      
          @QtCore.pyqtSlot()
          def on_button_clicked(self):
              self.procStart.emit(self.lineEdit.text())
      
          @QtCore.pyqtSlot(str)
          def on_widgetB_procDone(self, message):
              self.lineEdit.setText("From B: " + message)
      
              self.raise_()
      
      
      class mainwindow(QtWidgets.QMainWindow):
          def __init__(self, parent=None):
              super(mainwindow, self).__init__(parent)
      
              self.button = QtWidgets.QPushButton("Click Me", self)
              self.button.clicked.connect(self.on_button_clicked)
      
              self.setCentralWidget(self.button)
      
              self.widgetA = widgetA()
              self.widgetB = widgetB()
      
              self.widgetA.procStart.connect(self.widgetB.on_procStart)
              self.widgetB.procDone.connect(self.widgetA.on_widgetB_procDone)
      
          @QtCore.pyqtSlot()
          def on_button_clicked(self):
              self.widgetA.show()
              self.widgetB.show()
      
              self.widgetA.raise_()
      
      
      if __name__ == "__main__":
          import sys
      
          app = QtWidgets.QApplication(sys.argv)
          main = mainwindow()
          main.show()
          sys.exit(app.exec_())
      
      
      JonB JKSH 2 Replies Last reply Reply Quote 0
      • JonB
        JonB @Zac15 last edited by JonB

        @Zac15 said in How to transfer data between two widgets if they can't get each other's instance directly:

        In such case, is there a way to make widgetA and widgetB transfer data by using signal/slot or other mechanism, if they can't get each other's instance?

        Yes. It is main window which knows about both of them

        , the widgetA and widgetB can communicate with each other because their instances can be accessed from mainwindow Class.

        So let main window do the connect() of some signal emitted by one widget to some slot defined in the other widget. Your own signals and slots. Pass whatever minimal parameter(s) might be required to do whatever job. There should be no reason why one widget needs to actually access the other widget.

        You seem to already know this when I see you have self.procStart.emit(self.lineEdit.text())? And you have

                self.widgetA.procStart.connect(self.widgetB.on_procStart)
                self.widgetB.procDone.connect(self.widgetA.on_widgetB_procDone)
        

        Oh, I see, you seem to know this! Then

        But in my case, I am going to create extensions(widgetA and widgetB) from mainwindow , and the two sub widgets are in different project folders. I can't control how mainwindow initiates the two instances.

        I don't get this. If mainwindow has the two instances it should be able to do the connect(). So what is your exact situation?

        1 Reply Last reply Reply Quote 2
        • Z
          Zac15 last edited by Zac15

          Hi @JonB ,

          thank you for your reply.

          In my case, I don't have any control of the main window, so I can't get widgetA and widgetB objects in the main window.

          My question is if there is a way to send signal from widgetA, then widgetB can connect the signal without knowing(getting) widgetA object? Connecting a signal by the name of it.

          Because main window, widgetA, widgetB are in the same thread, is it possible to send signal to message(main) loop and catching it by the name?

          Cheers

          jsulm 1 Reply Last reply Reply Quote 0
          • jsulm
            jsulm Lifetime Qt Champion @Zac15 last edited by

            @Zac15 said in How to transfer data between two widgets if they can't get each other's instance directly:

            Connecting a signal by the name of it.

            Not possible, because objects emit signals. So, you need the emitting object and you need receiving object to connect. Somewhere in your application you should be able to have both instances to connect.

            "I don't have any control of the main window" - but in the code you posted you clearly create both objects in main window.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            Z 1 Reply Last reply Reply Quote 0
            • Z
              Zac15 @jsulm last edited by

              Hi @jsulm,

              If connecting a signal by its name is impossible, then I have to find another way to resolve the problem.

              Sorry, the code is just an example, while in my real work, I can't create objects in the main window.

              Thanks.

              Cheers.

              1 Reply Last reply Reply Quote 0
              • JKSH
                JKSH Moderators @Zac15 last edited by

                @Zac15 said in How to transfer data between two widgets if they can't get each other's instance directly:

                I can't control how mainwindow initiates the two instances.

                1. Can you work together with the person(s) who have control over mainwindow?
                2. The mainwindow obviously has a reason to instantiate your widgets. Does it provide any mechanism for your widgets to send/receive data?

                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                Z 1 Reply Last reply Reply Quote 0
                • Z
                  Zac15 @JKSH last edited by Zac15

                  Hi @JKSH,

                  I don't have any control to the mainwindow.

                  But I contacted the mainwindow developers, and they told me a way to get the objects of the child widgets from mainwindow.

                  They didn't document that, but there is an internal function to fetch children objects, which resolved my problem.

                  Thanks for your help.

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post