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 Updated to NodeBB v4.3 + New Features

Send data packets to multiple windows/widgets

Scheduled Pinned Locked Moved Solved Qt for Python
12 Posts 4 Posters 2.3k Views 2 Watching
  • 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on 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
    • JonBJ JonB

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

      JonBJ 1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on 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

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

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on 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
          1
          • JonBJ JonB

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

            JonBJ 1 Reply Last reply
            0
            • T tilz0R

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

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on 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
              1
              • JonBJ JonB

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

                JonBJ 1 Reply Last reply
                0
                • T tilz0R

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

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on 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

                    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 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
                    0
                    • M mpergand

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

                      • Login

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