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
-
@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(); }
-
@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...
-
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
-
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(); }