One signal to two window



  • Hello,

    Please give me a simple example code for the following:

    I have a "working thread" which has a variable.
    I would like to display this variable on two different GUI window.
    How can i do it?
    It is working for me with one window, but how can I use the same working thread signal to the two windows at the same time?



  • Connect the same signal in the second window slot and you will get both slots called on the signal.



  • Hello,

    Thank You!
    It is ok, i know, but I dont know how can I do it.
    Where have to declare and start the working thread, to use it both connect function?
    Sorry, but I never used before QT an C++ just C.



  • It depends on the architecture of you app.
    If it is a simple example that contains two windows then you can initialize everything in main() function()
    start thread
    create both windows
    connect all necessary signals

    "Here":http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ is a good explanation on how to use QThread in general.

    And a simple example
    @
    class WindowOne : public QWidget
    {
    ...
    public slots:
    void updateValue(int);
    ...
    };

    class WindowTwo : public QWidget
    {
    ...
    public slots:
    void updateValue(int);
    ...
    };

    class Worker : public QObject
    {
    ...
    signals:
    void valueChanged(int);
    };

    int main()
    {
    QApplication a(argc, argv);

    QThread* thread = new QThread;
    Worker* worker = new Worker;
    WindowOne* winOne = new WindowOne;
    WindowTwo* winTwo = new WindowTwo;
    
    connect(worker, &Worker::valueChanged, winOne, &WindowOne::updateValue);
    connect(worker, &Worker::valueChanged, winTwo, &WindowOne::updateValue);
    worker->moveToThread(thread);
    connect(thread, &QThread::started, worker, &Worker::process);
    connect(worker, &QThread::finished, thread, &QThread::quit);
    connect(worker, &QThread::finished, worker, &Worker::deleteLater);
    connect(thread, &QThread::finished, thread, &QThread::deleteLater);
    
    thread->start();
     
    winOne->show();
    winTwo->show();
    
    // Start app event loop
    return a.exec();
    

    }
    @



  • Thank You!

    It is working now if I open both windows in the main.
    How can I do it if I want to open the second window from a pushbutton of the first window?



  • There are multiple solutions.
    For example

    1. create second window and connect all necessary signals inside first window constructor. I think signals are not delivered if a window is not shown.
    2. In QPushButton::clicked() show second window.


  • I cant do it.



  • What do you mean. Are there any errors?
    Show what you have so far and we will help to fix it.



  • How can I use "QPushButton::clicked() show second window" in the main, if I have an UI window with that pushbutton? (I can open the second window from the first window, but than I cant make the connection between the worker thread and the second window with the same signal what iI use for the first window in the worker thread (because I initialized the worker in the main)).
    I tried to send a signal from that pushbutton, but I cant do to the main.
    My program is same now what you give me in the example.
    Thank You!



  • Add a pointer to Worker to WindowOne class. Initialize it in WindowOne constructor.
    Use it when you opening second window.



  • It is working now. I initialize the worker and the second window in the first window constructor. And connect everything there.
    Thank You!



  • Hello,
    I have an other conection problem now.
    I have a widget what I want to connect to my worker thread.
    My thread is initialized in other class (Mainwindow).

    widget .h:
    @class RoverSatView : public QWidget
    {
    Q_OBJECT
    public:
    RoverSatView(QWidget *parent = 0);

    protected:
    void paintEvent(QPaintEvent *event);

    private slots:
    void slot_rtk_rover_sat_azel_in(const SatList &sats);

    private:
        SatList satellites;
        rtk_thread worker;
    

    };

    widget .cpp:

    RoverSatView::RoverSatView(QWidget *parent) : QWidget(parent)
    {
    connect(&worker,SIGNAL(rtk_rover_sat_azel(const SatList)),this,SLOT(slot_rtk_rover_sat_azel_in(const SatList)));
    }@

    No error message, but not working. What is the misstake?
    Of course I have emit signal in the worker thread.



  • connect(&worker,SIGNAL(rtk_rover_sat_azel(const SatList)),this,SLOT(slot_rtk_rover_sat_azel_in(const SatList)));
    

    Did you register your SatList type?
    By the way, there is no need to use the const in the connect statement.



  • How do you assign worker from MainWindow to RoverSatView?
    Are there any message in a console when you start the app?



  • Yes, the SatList type is registered.
    No message in the consol.
    I have this in the class RoverSatView header:
    @ private:
    rtk_thread worker;
    @

    @MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    QThread* rtkthread=new QThread;
    rtk_thread* worker=new rtk_thread;
    

    ...
    worker->moveToThread(rtkthread);
    connect(rtkthread, SIGNAL(started()), worker, SLOT(run()));
    connect(worker, SIGNAL(finished()), rtkthread, SLOT(quit()));
    connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    connect(rtkthread, SIGNAL(finished()), rtkthread, SLOT(deleteLater()));
    rtkthread->start();

    }
    @
    @class RoverSatView : public QWidget
    {
    Q_OBJECT
    public:
    RoverSatView(QWidget *parent = 0);

    protected:
    void paintEvent(QPaintEvent *event);

    private slots:
    void slot_rtk_rover_sat_azel_in(const SatList &sats);

    private:
        SatList satellites;
        rtk_thread worker;
    

    };@



  • You start thread for one worker object in MainWindow and connect signals from different worker object in RoverSatView.



  • How can I conect in RoverSatView to the same worker as in MainWindow?



  • If RoverSatView is a member of MainWindow then you can declare worker as member of MainWindow and then pass it RoverSatView constructor.
    If it is not then allocate worker before MainWindow, pass it to MainWindow ctor and to RoverSatView.



  • Hello,

    How can I pass it if RoverSatView is a widget in a generated UI tabwidget?



  • then where you have the generation code you simply take that variable from there - from the constructor and connect it. just after it was constructed or generated



  • It is not working for me. "....was not declared in this scope"
    How can I pass a variable to a designer generated ui object?



  • Here is an example based on the sources you posted before.
    See my comments below started with // <<

    • MainWindow.h
      @
      class MainWindow : public QMainWindow
      {
      ...
      rtk_thread* worker; // << Declare worker in MainWindow
      RoverSatView* roverSatView;
      };
      @

    • MainWindow.cpp
      @
      MainWindow::MainWindow(QWidget *parent)
      : QMainWindow(parent)
      , ui(new Ui::MainWindow)
      {
      ui->setupUi(this);

      QThread* rtkthread = new QThread;
      worker = new rtk_thread; // << Initialize it in ctor
      ...
      worker->moveToThread(rtkthread);
      connect(rtkthread, SIGNAL(started()), worker, SLOT(run()));
      connect(worker, SIGNAL(finished()), rtkthread, SLOT(quit()));
      connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
      connect(rtkthread, SIGNAL(finished()), rtkthread, SLOT(deleteLater()));
      rtkthread->start();
      }

    void MainWindow::createRoverSatView()
    {
    roverSatView = new RoverSatView(worker, this); // << pass it to RoverSatView
    ...
    }
    @

    • RoverSatView.h
      @
      class RoverSatView : public QWidget
      {
      Q_OBJECT
      public:
      RoverSatView(rtk_thread* rtkWorker, QWidget *parent = 0);
      // << ctor accepts the worker from MainWindow

      protected:
      void paintEvent(QPaintEvent *event);

      private slots:
      void slot_rtk_rover_sat_azel_in(const SatList &sats);

      private:
      SatList satellites;
      rtk_thread* worker; // << it will keep worker from MainWindow
      };
      @

    • RoverSatView.cpp
      @
      RoverSatView::RoverSatView(rtk_thread* rtkWorker, QWidget* parent)
      : QWidget(parent)
      , worker(rtkWorker) // << initialize using worker from MainWindow
      {
      // Initialize the Qt magic
      connect(worker, SIGNAL(rtk_rover_sat_azel(SatList)),
      this, SLOT(slot_rtk_rover_sat_azel_in(SatList)));
      }
      @



  • Thank You for Your help!
    It is working now in a window, but I would like to add this RoverSatView to a tab of a tabwidget which is created in the creator. Is it possible, or I have to create the tabwidget in the code?



  • You can use "QTabWidget::addTab()":http://qt-project.org/doc/qt-5/qtabwidget.html#addTab to put your widget into generated QTabWidget



  • Hello,

    This is working:
    @connect(worker,SIGNAL(active_window(double)),this,SLOT(slot_active_window(double)));@

    This is not working:
    @connect(this,SIGNAL(active_window(double)),worker,SLOT(slot_active_window(double)));@

    Both in same place. I want to connect the thread (worker) and a window (this) in both direction.
    Why the second not working? Or I have to put the "connect..." to the SLOT side?



  • What do you mean "is not working".
    Compiler error or run-time error?
    Are there any run time messages on a console?
    Could you show a declaration of the signals and the slots in both classes.



  • No error and no messages, just the value is not send or receive from MainWindow to worker. From worker to MainWidow working, value send and receive.
    @
    class rtk_thread:public QObject
    {
    Q_OBJECT
    public:
    rtk_thread();
    ~rtk_thread();

    signals:
    void active_window(double);

    private slots:
    void slot_active_window(double);

    };@

    @class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

     Ui::MainWindow *ui;
    
     QDialog *win_GPS;
     rtk_thread* worker;
    

    public slots:

    private slots:
    void slot_active_window(double);

    signals:
    void active_window(double);

    private:
    };@
    MaiWidow.cpp
    @MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    QThread* rtkthread=new QThread;
    worker=new rtk_thread;
    win_GPS = new GPSwindow(worker);
    

    worker->moveToThread(rtkthread);
    connect(rtkthread, SIGNAL(started()), worker, SLOT(run()));
    connect(worker, SIGNAL(finished()), rtkthread, SLOT(quit()));
    connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    connect(rtkthread, SIGNAL(finished()), rtkthread, SLOT(deleteLater()));
    rtkthread->start();
    connect(this,SIGNAL(active_window(double)),worker,SLOT(slot_active_window(double)));
    connect(worker,SIGNAL(active_window(double)),this,SLOT(slot_active_window(double)));
    }@


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.