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. Send data packets to multiple windows/widgets
Forum Update on Monday, May 27th 2025

Send data packets to multiple windows/widgets

Scheduled Pinned Locked Moved Solved Qt for Python
12 Posts 4 Posters 2.2k 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.
  • T Offline
    T Offline
    tilz0R
    wrote on 24 Feb 2023, 17:14 last edited by
    #1

    I have one QMainWindow that opens DLL and receives data from it.
    This QMainWindow has different other windows opened, and holds its reference to it.

    I'd like to make a generic "driver" where each new window can subscribe to receive packets coming from DLL. Right now, when DLL packet arrives, it gets written to queue, which is later processed in QTimer callback, every 50ms at the moment.

    What is the correct and suggested way from Qt to achieve such task?

    I see one option with signals:

    • QMainWindow creates signal object that is emitted on every DLL message
    • New window, when created, receives pointer to parent, and can subscribe to signal. Signal will therefore have multiple connections
    • Use closeEvent to disconnect from signal

    Is this the right way?

    J M 2 Replies Last reply 24 Feb 2023, 18:35
    0
    • T tilz0R
      24 Feb 2023, 17:14

      I have one QMainWindow that opens DLL and receives data from it.
      This QMainWindow has different other windows opened, and holds its reference to it.

      I'd like to make a generic "driver" where each new window can subscribe to receive packets coming from DLL. Right now, when DLL packet arrives, it gets written to queue, which is later processed in QTimer callback, every 50ms at the moment.

      What is the correct and suggested way from Qt to achieve such task?

      I see one option with signals:

      • QMainWindow creates signal object that is emitted on every DLL message
      • New window, when created, receives pointer to parent, and can subscribe to signal. Signal will therefore have multiple connections
      • Use closeEvent to disconnect from signal

      Is this the right way?

      M Offline
      M Offline
      mpergand
      wrote on 25 Feb 2023, 11:19 last edited by mpergand
      #11

      @tilz0R said in Send data packets to multiple windows/widgets:

      I have one QMainWindow that opens DLL and receives data from it.
      This QMainWindow has different other windows opened, and holds its reference to it.

      If mainWindow has a ref to child windows, why not send data directly to them ?
      To manage child windows deleting, you can use QPointer as it will be set to null.
      Here a standalone example:

      class ChildWindow : public QWidget
      {
          public:
              ChildWindow(QWidget* parent=nullptr) : QWidget(parent)
                  {
                      setAttribute(Qt::WA_DeleteOnClose);
                  }
      
              void setData(const QByteArray& data)
                  {
                  qDebug()<<objectName()<<data;
                  }
      };
      
      class MainWin : public QMainWindow
      {
          public:
              MainWin() : QMainWindow()
                  {
                  // use a timer to simulate incoming data
                  QTimer* timer=new QTimer(this);
                  connect(timer, &QTimer::timeout,this,[this]()
                  {
                      static int i=0;
                      i++;
      
                      auto it = childWindows.begin();
      
                      while (it != childWindows.end())
                          {
                          if (*it==nullptr)   // removed from the vector if child win deleted/closed
                              it = childWindows.erase(it);
                          else
                              {
                              (**it).setData(QString("Data %1").arg(i).toLatin1());
                              ++it;
                              }
                          }
                  });
                  
                  timer->start(1000);
      
                  for(int i=0; i<3; i++)
                      {
                      ChildWindow* w=new ChildWindow;
                      w->setObjectName(QString("Child %1").arg(i+1));
                      w->setWindowTitle(w->objectName());
                      w->show();
                      childWindows<<w;
                      }
      
                  }
      
          private:
              QVector<QPointer<ChildWindow> > childWindows;
      
      };
      
      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
      
      MainWin win;
      win.setWindowTitle("Main WIndow");
      win.show();
          return app.exec();
      }
      
      T 1 Reply Last reply 28 Feb 2023, 21:04
      0
      • T tilz0R
        24 Feb 2023, 17:14

        I have one QMainWindow that opens DLL and receives data from it.
        This QMainWindow has different other windows opened, and holds its reference to it.

        I'd like to make a generic "driver" where each new window can subscribe to receive packets coming from DLL. Right now, when DLL packet arrives, it gets written to queue, which is later processed in QTimer callback, every 50ms at the moment.

        What is the correct and suggested way from Qt to achieve such task?

        I see one option with signals:

        • QMainWindow creates signal object that is emitted on every DLL message
        • New window, when created, receives pointer to parent, and can subscribe to signal. Signal will therefore have multiple connections
        • Use closeEvent to disconnect from signal

        Is this the right way?

        J Offline
        J Offline
        JonB
        wrote on 24 Feb 2023, 18:35 last edited by
        #2

        @tilz0R
        This is about how I would do it in Qt. Except I wouldn't pass a "pointer to parent [main window]" to other windows. Create an object to emit the signals rather than having it a part of the main window, other windows can place slots on it without accessing the main window.

        T 1 Reply Last reply 24 Feb 2023, 19:44
        1
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 24 Feb 2023, 19:16 last edited by
          #3

          Hi,

          As @JonB suggests, create a controller object that manages the interaction with that dll.

          You can then have an instance of it in your main window and connect all the "sub-windows" to that controller.

          From the looks of it, none of these widgets needs to know anything about the controller. Give them a proper slot to receive the data.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          1
          • J JonB
            24 Feb 2023, 18:35

            @tilz0R
            This is about how I would do it in Qt. Except I wouldn't pass a "pointer to parent [main window]" to other windows. Create an object to emit the signals rather than having it a part of the main window, other windows can place slots on it without accessing the main window.

            T Offline
            T Offline
            tilz0R
            wrote on 24 Feb 2023, 19:44 last edited by
            #4

            @JonB So your suggestion is to have a singleton object(that extends QObject) where each new instance who wants to receive packets, can get instance and connect to it?

            J 1 Reply Last reply 24 Feb 2023, 20:23
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 24 Feb 2023, 19:47 last edited by
              #5

              There's no need for any singleton.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • T tilz0R
                24 Feb 2023, 19:44

                @JonB So your suggestion is to have a singleton object(that extends QObject) where each new instance who wants to receive packets, can get instance and connect to it?

                J Offline
                J Offline
                JonB
                wrote on 24 Feb 2023, 20:23 last edited by JonB
                #6

                @tilz0R
                If you allow the main window to have the instance and connect to publicly exposed slots in the windows it creates then it can do the connects. The spawned windows do not do the connecting. That is what @SGaist is suggesting. So no need for a singleton.

                T 1 Reply Last reply 25 Feb 2023, 08:14
                1
                • J JonB
                  24 Feb 2023, 20:23

                  @tilz0R
                  If you allow the main window to have the instance and connect to publicly exposed slots in the windows it creates then it can do the connects. The spawned windows do not do the connecting. That is what @SGaist is suggesting. So no need for a singleton.

                  T Offline
                  T Offline
                  tilz0R
                  wrote on 25 Feb 2023, 08:14 last edited by
                  #7

                  @JonB This will then allow to receive slots from spawn windows to the main one. Correct?

                  What about the opposite way? Is there a good example not to shoot myself to the knee?

                  J 1 Reply Last reply 25 Feb 2023, 08:47
                  0
                  • T tilz0R
                    25 Feb 2023, 08:14

                    @JonB This will then allow to receive slots from spawn windows to the main one. Correct?

                    What about the opposite way? Is there a good example not to shoot myself to the knee?

                    J Offline
                    J Offline
                    JonB
                    wrote on 25 Feb 2023, 08:47 last edited by JonB
                    #8

                    @tilz0R
                    Yes, main window will go

                        this->otherWindow = new OtherWindow(this);
                        connect(this->dllSignaller, &DllSignaller::packetArrived,
                                this->otherWindow, &OtherWindow::onPacketArrivedSlot);
                    

                    The "opposite way", assuming you mean the "other windows" would have to know about the main window in order to get at the DLL signaller object, is not a good design. It means they are dependent on your main window, while there is no need for them to be. The general rule is it's OK for parents to know about children but try to make children not know about parents.

                    T 1 Reply Last reply 25 Feb 2023, 08:53
                    1
                    • J JonB
                      25 Feb 2023, 08:47

                      @tilz0R
                      Yes, main window will go

                          this->otherWindow = new OtherWindow(this);
                          connect(this->dllSignaller, &DllSignaller::packetArrived,
                                  this->otherWindow, &OtherWindow::onPacketArrivedSlot);
                      

                      The "opposite way", assuming you mean the "other windows" would have to know about the main window in order to get at the DLL signaller object, is not a good design. It means they are dependent on your main window, while there is no need for them to be. The general rule is it's OK for parents to know about children but try to make children not know about parents.

                      T Offline
                      T Offline
                      tilz0R
                      wrote on 25 Feb 2023, 08:53 last edited by
                      #9

                      @JonB OK - thanks makes sense in DLL direction. I suppose main window should then do the same to detect when child window is closed (but not destroyed in the memory). To disconnect sending packets there.

                      J 1 Reply Last reply 25 Feb 2023, 09:53
                      0
                      • T tilz0R
                        25 Feb 2023, 08:53

                        @JonB OK - thanks makes sense in DLL direction. I suppose main window should then do the same to detect when child window is closed (but not destroyed in the memory). To disconnect sending packets there.

                        J Offline
                        J Offline
                        JonB
                        wrote on 25 Feb 2023, 09:53 last edited by
                        #10

                        @tilz0R
                        It could, if say you make the child emit a "closed" signal by overriding its closeEvent(). And then you'll have to attach its re-open event too.

                        Or, why does the main window actually need to detach closed child from signal? Child could equally detect it is closed and not both to do work in its slot.

                        1 Reply Last reply
                        0
                        • T tilz0R
                          24 Feb 2023, 17:14

                          I have one QMainWindow that opens DLL and receives data from it.
                          This QMainWindow has different other windows opened, and holds its reference to it.

                          I'd like to make a generic "driver" where each new window can subscribe to receive packets coming from DLL. Right now, when DLL packet arrives, it gets written to queue, which is later processed in QTimer callback, every 50ms at the moment.

                          What is the correct and suggested way from Qt to achieve such task?

                          I see one option with signals:

                          • QMainWindow creates signal object that is emitted on every DLL message
                          • New window, when created, receives pointer to parent, and can subscribe to signal. Signal will therefore have multiple connections
                          • Use closeEvent to disconnect from signal

                          Is this the right way?

                          M Offline
                          M Offline
                          mpergand
                          wrote on 25 Feb 2023, 11:19 last edited by mpergand
                          #11

                          @tilz0R said in Send data packets to multiple windows/widgets:

                          I have one QMainWindow that opens DLL and receives data from it.
                          This QMainWindow has different other windows opened, and holds its reference to it.

                          If mainWindow has a ref to child windows, why not send data directly to them ?
                          To manage child windows deleting, you can use QPointer as it will be set to null.
                          Here a standalone example:

                          class ChildWindow : public QWidget
                          {
                              public:
                                  ChildWindow(QWidget* parent=nullptr) : QWidget(parent)
                                      {
                                          setAttribute(Qt::WA_DeleteOnClose);
                                      }
                          
                                  void setData(const QByteArray& data)
                                      {
                                      qDebug()<<objectName()<<data;
                                      }
                          };
                          
                          class MainWin : public QMainWindow
                          {
                              public:
                                  MainWin() : QMainWindow()
                                      {
                                      // use a timer to simulate incoming data
                                      QTimer* timer=new QTimer(this);
                                      connect(timer, &QTimer::timeout,this,[this]()
                                      {
                                          static int i=0;
                                          i++;
                          
                                          auto it = childWindows.begin();
                          
                                          while (it != childWindows.end())
                                              {
                                              if (*it==nullptr)   // removed from the vector if child win deleted/closed
                                                  it = childWindows.erase(it);
                                              else
                                                  {
                                                  (**it).setData(QString("Data %1").arg(i).toLatin1());
                                                  ++it;
                                                  }
                                              }
                                      });
                                      
                                      timer->start(1000);
                          
                                      for(int i=0; i<3; i++)
                                          {
                                          ChildWindow* w=new ChildWindow;
                                          w->setObjectName(QString("Child %1").arg(i+1));
                                          w->setWindowTitle(w->objectName());
                                          w->show();
                                          childWindows<<w;
                                          }
                          
                                      }
                          
                              private:
                                  QVector<QPointer<ChildWindow> > childWindows;
                          
                          };
                          
                          int main(int argc, char *argv[])
                          {
                              QApplication app(argc, argv);
                          
                          MainWin win;
                          win.setWindowTitle("Main WIndow");
                          win.show();
                              return app.exec();
                          }
                          
                          T 1 Reply Last reply 28 Feb 2023, 21:04
                          0
                          • M mpergand
                            25 Feb 2023, 11:19

                            @tilz0R said in Send data packets to multiple windows/widgets:

                            I have one QMainWindow that opens DLL and receives data from it.
                            This QMainWindow has different other windows opened, and holds its reference to it.

                            If mainWindow has a ref to child windows, why not send data directly to them ?
                            To manage child windows deleting, you can use QPointer as it will be set to null.
                            Here a standalone example:

                            class ChildWindow : public QWidget
                            {
                                public:
                                    ChildWindow(QWidget* parent=nullptr) : QWidget(parent)
                                        {
                                            setAttribute(Qt::WA_DeleteOnClose);
                                        }
                            
                                    void setData(const QByteArray& data)
                                        {
                                        qDebug()<<objectName()<<data;
                                        }
                            };
                            
                            class MainWin : public QMainWindow
                            {
                                public:
                                    MainWin() : QMainWindow()
                                        {
                                        // use a timer to simulate incoming data
                                        QTimer* timer=new QTimer(this);
                                        connect(timer, &QTimer::timeout,this,[this]()
                                        {
                                            static int i=0;
                                            i++;
                            
                                            auto it = childWindows.begin();
                            
                                            while (it != childWindows.end())
                                                {
                                                if (*it==nullptr)   // removed from the vector if child win deleted/closed
                                                    it = childWindows.erase(it);
                                                else
                                                    {
                                                    (**it).setData(QString("Data %1").arg(i).toLatin1());
                                                    ++it;
                                                    }
                                                }
                                        });
                                        
                                        timer->start(1000);
                            
                                        for(int i=0; i<3; i++)
                                            {
                                            ChildWindow* w=new ChildWindow;
                                            w->setObjectName(QString("Child %1").arg(i+1));
                                            w->setWindowTitle(w->objectName());
                                            w->show();
                                            childWindows<<w;
                                            }
                            
                                        }
                            
                                private:
                                    QVector<QPointer<ChildWindow> > childWindows;
                            
                            };
                            
                            int main(int argc, char *argv[])
                            {
                                QApplication app(argc, argv);
                            
                            MainWin win;
                            win.setWindowTitle("Main WIndow");
                            win.show();
                                return app.exec();
                            }
                            
                            T Offline
                            T Offline
                            tilz0R
                            wrote on 28 Feb 2023, 21:04 last edited by
                            #12

                            Thanks to all - I learnt something new, especially who shall call connect to signals.

                            1 Reply Last reply
                            0
                            • T tilz0R has marked this topic as solved on 2 Mar 2023, 14:47

                            1/12

                            24 Feb 2023, 17:14

                            • Login

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