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

How to correctly implement a function call immediately after creating an application window



  • 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


  • Lifetime Qt Champion

    Hi,

    Where is that parameter coming from ?



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

  • Lifetime Qt Champion

    It makes no difference if you set the parameter via the ctor or directly afterwards via setMessage()


  • Lifetime Qt Champion

    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.



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


  • @Helg1980
    Don't run it by a timer unless you have some explicit reason for needing to do so.

    Did you get this idea of running via a timer from somewhere in particular? And 18 is "strange" delay to want to use? :)



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



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



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


  • Lifetime Qt Champion

    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.



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

Log in to reply