How to correctly implement a function call immediately after creating an application window
-
wrote on 13 Nov 2020, 18:22 last edited by Helg1980
Hi!
Immediately after creating the window, I need to call a function that will set parameters for the application.
Is this decision correct:Taskcomplete::Taskcomplete(QWidget *parent, QString msg, bool tmd) : QDialog(parent), ui_taskcomplete(new Ui::Taskcomplete) { ui_taskcomplete->setupUi(this); setMessage(msg, tmd); } void Taskcomplete::setMessage(QString _message, bool _timer_mode) // Set parameters { }
It confuses me that the function is called directly from the constructor.
Sometimes for me this leads to incorrect display of styleSheet -
Hi,
Where is that parameter coming from ?
-
wrote on 13 Nov 2020, 18:27 last edited by
They are passed from MainWindow:
void MainWindow::call_task_complete(QString _message, bool _timer_mode) // Call task complete { Taskcomplete taskcomplete(this, _message, _timer_mode); taskcomplete.setModal(true); taskcomplete.exec(); }
-
It makes no difference if you set the parameter via the ctor or directly afterwards via setMessage()
-
You can do it like that or use the corresponding setters from your MainWindow. That second option will avoid you to modify your constructor if you need to add or remove parameters.
On a side note, it's more common to have parent as the last parameter of the constructor so your use a nullptr as default value for it.
-
wrote on 13 Nov 2020, 18:42 last edited by Helg1980
It turned out something like this:
void MainWindow::call_task_complete(QString _message, bool _timer_mode) { Taskcomplete taskcomplete(this); taskcomplete.setMessage(_message, _timer_mode); // Set parameters taskcomplete.setModal(true); taskcomplete.exec(); }
But another question is, when the program starts, is it correct to call the function from the constructor? Or is it better to run the function via a timer?
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QTimer::singleShot(18, this, SLOT(setParameters())); }
-
It turned out something like this:
void MainWindow::call_task_complete(QString _message, bool _timer_mode) { Taskcomplete taskcomplete(this); taskcomplete.setMessage(_message, _timer_mode); // Set parameters taskcomplete.setModal(true); taskcomplete.exec(); }
But another question is, when the program starts, is it correct to call the function from the constructor? Or is it better to run the function via a timer?
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QTimer::singleShot(18, this, SLOT(setParameters())); }
-
wrote on 13 Nov 2020, 18:57 last edited by Helg1980
Yes, on one Russian-language forum I read that I can use the timer to start the function, but I'm not sure that this is correct.
I have repeatedly noticed that if I run a function in the constructor, the window elements are displayed incorrectly. Pause 18 milliseconds selected at random.
-
Yes, on one Russian-language forum I read that I can use the timer to start the function, but I'm not sure that this is correct.
I have repeatedly noticed that if I run a function in the constructor, the window elements are displayed incorrectly. Pause 18 milliseconds selected at random.
wrote on 13 Nov 2020, 19:01 last edited by JonB@Helg1980 said in How to correctly implement a function call immediately after creating an application window:
I have repeatedly noticed that if I run a function in the constructor, the window elements are displayed incorrectly.
That itself sounds odd. You would have to look at/show what your code is actually doing. My guess is that you are doing something which needs to happen "later", for some reason. And I would guess if you put that time delay up to
1800
it would probably never go wrong :)Sometimes things are best done in, say, the
showEvent()
of a window/dialog opening.We would need to know why the Russian code used a timer, and how it relates to your situation!
You could always put
qDebug()
messages into the constructors and the timed methods to see what order things actually get executed in. You might notice a difference/problem. -
wrote on 13 Nov 2020, 19:11 last edited by Helg1980
When my code looked like this:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); set_theme(0); // Set theme ui->label_53->hide(); ui->label_54->hide(); ui->label_55->hide(); ui->progressBar->hide(); ui->tableWidget->setColumnWidth(0, 250); ui->tableWidget->setColumnWidth(1, 80); ui->tableWidget->setColumnWidth(2, 85); ui->tableWidget->resizeColumnToContents(3); ui->tableWidget->setColumnWidth(4, 70); ui->tableWidget->setColumnWidth(5, 60); . . . } void MainWindow::set_theme(int ind_theme) // Set theme { QFile file; switch (ind_theme) { case 0: { file.setFileName(":/style_default.css"); ui->frame_main->setStyleSheet("background-color: rgb(5, 20, 28);"); }; break; case 1: { file.setFileName(":/style_deep.css"); ui->frame_main->setStyleSheet("background-color: rgb(3, 3, 5);"); }; break; case 2: { file.setFileName(":/style_wave.css"); ui->frame_main->setStyleSheet("background-color: rgb(39, 44, 54);"); }; break; case 3: { file.setFileName(":/style_white.css"); ui->frame_main->setStyleSheet("background-color: rgb(77, 80, 87);"); }; break; } file.open(QFile::ReadOnly); QString list = file.readAll(); ui->frame_1->setStyleSheet(list); }
, styleSheet was displayed incorrectly and the width of the table columns was set incorrectly.
Therefore, the task was to cause a change in the graphical environment with a delay. -
The usual reason to use a single shot QTimer from a constructor is to trigger a method that will result in a chain of updates sprinkled around some or all widgets or objects created before "app.exec()" is called.
In any case, it's something that must be properly thought about because of all the implication it may have.
-
wrote on 13 Nov 2020, 20:41 last edited by
As a result, I used showEvent():
void MainWindow::showEvent(QShowEvent *event) // Call set parameters { std::cout << "Window activate: " << event->WindowActivate << std::endl; // Debug info // setParameters(); }
1/12