Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Passing Updated Data to Second Window



  • Howdy,

    I seem to be stuck coming up with a way to have main window data, which gets updated every X seconds, appear on my second window such that the second window fields get updated every X seconds.

    My code gets the first pass of data to the second window no problem, I just can't seem to get my head around how to update the data in the second window every time it updates in the main window.

    Do I use a signal/slot; if so what signal do I use to initiate the slot; does the signal/slot run from the main window or the second window? (The second window can't see the main window as far as I know so not sure how I would get that to work.)

    Do I need another timer; which window is going to be responsible for sending/getting the updated data?
    I can picture all this in my head, but can't convert it to Qt code yet...

    The second window is opened with a pushbutton click in the main window.
    And, of course, nothing should happen if the second window is not open or is closed.

    The pertinent code for this as it stands now:

    mainwindow.h
    
    #include "dialogtest.h"
    
    private:
    	// second window
        DialogTest *dialogTest;
    
    	// data to pass to second window
        QStringList cpuStats;
    
    
    mainwindow.cpp
    
    void MainWindow::leftbutton_clicked()
    {
        dialogTest = new DialogTest(this);
        dialogTest->show();
        dialogTest->passData(cpuStats);
    }
    
    
    dialogtest.h
    
    public:
        explicit DialogTest(QWidget *parent = nullptr);
        ~DialogTest();
    
        // gets called from MainWindow when button pressed to open this window
        void passData(QStringList myData);
    
    
    dialogtest.cpp
    
    void DialogTest::passData(QStringList myData)
    {
        ui->label_test1->setText(myData[0]);
        ui->label_test2->setText(myData[1]);
        ui->label_test3->setText(myData[2]);
    }
    

    Ideas deeply appreciated! Thx...IanQ



  • @IanQ
    Yes you would, or might, use some signal and slot, but

    • How is this data getting updated?
    • Why would you want "main window data" copied into a second window at all?


  • @JonB
    I run a timer in the main window that executes an external OS command via an asynchronous process to retrieve the data every X seconds.

    I display some data on the main window, somewhat of an overview, but want to have the second window display all the data for a more detailed view. The full data only gets displayed if the user decides to open the second window, thus why I collect it in the main window.

    I have some rough code working now that updates the second window, basically when the second window is opened it starts its own timer that emits a signal back to the main window to send the data every X seconds. It does what I want it to, just not sure it is the proper way to do this. Will add the new code to this post shortly.

    Ian



  • Okay, got something working, as mentioned to JonB, the new code basically starts a new timer in the second window when opened, and this timer emits a signal every X seconds back to the main window to resend the data to the second window. Sounds messy to me so if anyone has a more elegant way, please do share...Ian

    
    mainwindow.h
    
    #include "dialogtest.h"
    
    public slots:
        void Pass_Data_To_CPU_Window();
    
    private:
        // second window
        DialogTest *dialogTest;
    
        // system stats timer
        QTimer *timerStats;
    
        // data to pass to second window
        QStringList cpuStats;
    
    
    mainwindow.cpp
    
    MainWindow::MainWindow(QString cmdlineArgument, QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        // run system stats timer
        timerStats = new QTimer(this);
        QObject::connect(timerStats, SIGNAL(timeout()), this, SLOT(Update_Stats_Timer()));
        timerStats->start(timerInterval);
    }
    
    // get stats via 'timerStats' timer
    void MainWindow::Update_Stats_Timer()
    {
        Get_CPU_Load();
        Get_Memory_Swap();
        Get_Memory_Stats();
        Get_Top_Stats();
        Get_Netstat_Stats();
        Get_IOstat_Stats();
    }
    
    // pass data to second window
    void MainWindow::Pass_Data_To_CPU_Window()
    {
        dialogTest->passData(cpuStats);
    }
    
    // open second window
    void MainWindow::leftbutton_clicked()
    {
        dialogTest = new DialogTest(this);
        connect(dialogTest, SIGNAL(CPU_Window()), this, SLOT(Pass_Data_To_CPU_Window()));
        dialogTest->show();
        dialogTest->passData(cpuStats);
    }
    
    
    dialogtest.h
    
    public:
        explicit DialogTest(QWidget *parent = nullptr);
        ~DialogTest();
    
        void passData(QStringList myData);
    
    signals:
        void CPU_Window();
    
    private slots:
        void Emit_CPU_Window();
    
    private:
        Ui::DialogTest *ui;
    
        // system stats timer
        QTimer *timerStatsDialog;
    
    
    dialogtest.cpp
    
    DialogTest::DialogTest(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::DialogTest)
    {
        ui->setupUi(this);
    
        // run system stats timer
        timerStatsDialog = new QTimer(this);
        connect(timerStatsDialog, SIGNAL(timeout()), this, SLOT(Emit_CPU_Window()));
        timerStatsDialog->start(1000);
    
    }
    
    void DialogTest::passData(QStringList myData)
    {
        ui->label_test1->setText(myData[0]);
        ui->label_test2->setText(myData[1]);
        ui->label_test3->setText(myData[2]);
    
    }
    
    void DialogTest::Emit_CPU_Window()
    {
        emit CPU_Window();
    }
    
    

  • Lifetime Qt Champion

    @IanQ said in Passing Updated Data to Second Window:

    when the second window is opened it starts its own timer that emits a signal back to the main window to send the data every X seconds

    Sounds complicated. Simply connect the slot of the second window to the timer in main window...



  • @jsulm

    Your suggestion certainly sounds simpler, but I can't see how to implement this.

    I updated my code snippet above to include my main window timer code.

    I am assuming the change I need to make is in leftButton_Clicked() where I connect the second window, but I don't see how to implement the timer into the SLOT(), not sure what I need to place there.

    Also, the current slot has the function for actually passing the code, replacing that with a reference to the timer, how will I get the updated data passed?

    Signal/Slots still a big challenge to me...Ian


  • Lifetime Qt Champion

    @IanQ

    void MainWindow::leftbutton_clicked()
    {
        dialogTest = new DialogTest(this);
        connect(dialogTest, SIGNAL(CPU_Window()), this, SLOT(Pass_Data_To_CPU_Window()));
        connect(timerStats, SIGNAL(timeout()), dialogTest, SLOT(Update_Stats_Timer())); // Change slot name as needed
        dialogTest->show();
        dialogTest->passData(cpuStats);
    }
    


  • @IanQ said in Passing Updated Data to Second Window:

    I am assuming the change I need to make is in leftButton_Clicked() where I connect the second window, but I don't see how to implement the timer into the SLOT(), not sure what I need to place there.

    Put something like

    QObject::connect(timerStats, &QTimer::timeout, dialogTest, &DialogTest::YOUR_SLOT_IN_DIALOG);
    


  • Sweet...this code is much cleaner, nice to do away with the timer in the second window.

    What had me going down the rabbit hole was the thought that I should only have 1 signal/slot to the second window, a newbie mistake, and more so my mistake as I was aware that you could have as many signal/slots as you need, that info was just lost somewhere in my old decaying brain.

    So my connects look like:

            connect(dialogTest, &DialogTest::CPU_Window, this, &MainWindow::Pass_Data_To_CPU_Window);
            connect(timerStats, &QTimer::timeout, dialogTest, &DialogTest::Emit_Request_Data_Update);
            
    

    I have been wanting to move from the old style signal/slot format to the newer syntax, have done so here.

    Will post the final pertinent code before closing and marking this as solved.

    Thanks much for the help folks



  • Here are the final code snippets to allow the second window to receive from the main window data that is being updated every X seconds via a timer event.

    mainwindow.h
    
    public slots:
        void Pass_Data_To_CPU_Window();
    
    private:
        // system stats timer
        QTimer *timerStats;
    
    	// second window
        DialogTest *dialogTest;
    
    	// data to pass to second window
        QStringList cpuStats;
    
    
    mainwindow.cpp
    
    MainWindow::MainWindow(QString cmdlineArgument, QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        // run system stats timer
        timerStats = new QTimer(this);
        connect(timerStats, &QTimer::timeout, this, &MainWindow::Update_Stats_Timer);
        timerStats->start(2000);
    
    // get stats via 'timerStats' timer
    void MainWindow::Update_Stats_Timer()
    {
        Get_CPU_Load();
        Get_Top_Stats();
    }
    
    void MainWindow::Pass_Data_To_CPU_Window()
    {
        dialogTest->passData(cpuStats);
    }
    
    void MainWindow::leftbutton_clicked()
    {
        dialogTest = new DialogTest(this);
        connect(dialogTest, &DialogTest::CPU_Window, this, &MainWindow::Pass_Data_To_CPU_Window);
        connect(timerStats, &QTimer::timeout, dialogTest, &DialogTest::Emit_Request_Data_Update);
        dialogTest->show();
    }
    
    
    dialogtest.h
    
    public:
        explicit DialogTest(QWidget *parent = nullptr);
        ~DialogTest();
    
        void passData(QStringList myData);
    
    signals:
        void CPU_Window();
    
    public slots:
        void Emit_Request_Data_Update();
    
    
    dialogtest.cpp
    
    void DialogTest::passData(QStringList myData)
    {
        ui->label_test1->setText(myData[0]);
        ui->label_test2->setText(myData[1]);
        ui->label_test3->setText(myData[2]);
    
    }
    
    void DialogTest::Emit_Request_Data_Update()
    {
        emit CPU_Window();
    }
    
    

Log in to reply