Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. How to transfer data between two widgets if they can't get each other's instance directly
QtWS25 Last Chance

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

Scheduled Pinned Locked Moved Solved Qt for Python
7 Posts 4 Posters 3.0k Views
  • 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 Offline
    Z Offline
    Zac15
    wrote on last edited by
    #1

    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_())
    
    
    JonBJ JKSHJ 2 Replies Last reply
    0
    • Z Zac15

      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_())
      
      
      JonBJ Online
      JonBJ Online
      JonB
      wrote on last edited by JonB
      #2

      @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
      2
      • Z Offline
        Z Offline
        Zac15
        wrote on last edited by Zac15
        #3

        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

        jsulmJ 1 Reply Last reply
        0
        • Z 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

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @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
          0
          • jsulmJ jsulm

            @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.

            Z Offline
            Z Offline
            Zac15
            wrote on last edited by
            #5

            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
            0
            • Z Zac15

              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_())
              
              
              JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by
              #6

              @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
              0
              • JKSHJ JKSH

                @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?
                Z Offline
                Z Offline
                Zac15
                wrote on last edited by Zac15
                #7

                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
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved