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

How to create a pop up message like message box with a countdown?



  • Hello, I'm new in Qt. I'm trying to create a message box with a countdown, how can I update the text show in the message without creating the message again?
    Thank for any help.


  • Moderators

    Hi @Z0mbi3 and welcome

    you can change the text of a QMessageBox any time via the setText() function.

    heres a working example:

    #include <QApplication>
    #include <QMessageBox>
    #include <QTimer>
    
    int main(int argc, char ** argv)
    {
        QApplication app(argc, argv);
    
        QMessageBox msg;
        msg.setText("This closes in 10 seconds");
    
        int cnt = 10;
    
        QTimer cntDown;
        QObject::connect(&cntDown, &QTimer::timeout, [&msg,&cnt, &cntDown]()->void{
                             if(--cnt < 0){
                                 cntDown.stop();
                                 msg.close();
                             } else {
                                 msg.setText(QString("This closes in %1 seconds").arg(cnt));
                             }
                         });
        cntDown.start(1000);
        msg.exec();
    }
    


  • Thanks @J-Hilk for your help, I really appreciate it, but now I have another question, I don't want to bother you but, can you explain what this code line do?
    QObject::connect(&cntDown, &QTimer::timeout, &msg,&cnt, &cntDown->void{…
    I'll be grateful if you take a time to answer this new question.


  • Lifetime Qt Champion

    @Z0mbi3 It connects timeout signal from the cntDown timer to a lambda (which is slot here). Lambdas are a C++11 feature, see https://en.cppreference.com/w/cpp/language/lambda
    In this case the lambda captures 3 parameters by reference: msg, cnt and cntDown, does not return anything and does not take any parameters.


  • Moderators

    @Z0mbi3 said in How to create a pop up message like message box with a countdown?:

    QObject::connect(&cntDown, &QTimer::timeout, &msg,&cnt, &cntDown->void{…

    Hi,

    there's a lot to unpack in that simple question :)

    But it's part of the essential functionality of Qt, know as the Signal&Slot mechanisms.
    For further read on the topic take a look at the documentation:
    https://doc.qt.io/qt-5/signalsandslots.html

    Let me boil it down for you.
    The QTimer-Object is emitting a signal(void timeout()) each time the set interval has passed. (1000 ms in the above example)

    with the connect function of the QObject class we listen to the timeout signal and decide what shall happen when the signal is emitted.

    In the above case, the signal is connected to a lambda function - more informations on lambdas can be found here: https://de.cppreference.com/w/cpp/language/lambda

    The objects msg, int and cntDown are captured for the lambda, so that they can be used inside of it,

    Inside the () would go any arguments that timeout has and would be used inside the lambda. It's empty because void timeout() has no arguments.

    ->void defines the return type of the lambda

    inside {} is the actual function



  • @J.Hilk thank again for your help, I´ll check the information about the lambda function, but I´m having a problem with your code, I can´t call another function inside the if sentence. Let me explain what I´m trying to do.
    I want to communicate trough serial port with a device, I'm using a function to set up all the parameters of the communication and try to open the port, in case it can't be opened it call a Wait function, here is when your code come in, the wait function show the text "The port can't be open. Retrying in 10 seconds." with two buttons the first one is "Retry now" and the second is "Change configuration", the first button call the configuration function and the second call another windows where the user can change the parameter of the communication "port name, bauds rate, etc" but I also need to call the configuration function when the timeout end, I want to put this inside the if sentence but show me this error
    ...\mainwindow.cpp:240: error: 'this' was not captured for this lambda function
    Config_puerto_serie(Commport);
    : error: 'this' cannot be implicitly captured in this context
    You have some clue to guide me?

                                                          ^

  • Lifetime Qt Champion

    @Z0mbi3 said in How to create a pop up message like message box with a countdown?:

    ...\mainwindow.cpp:240: error: 'this' was not captured for this lambda function
    Config_puerto_serie(Commport);
    : error: 'this' cannot be implicitly captured in this context

    Better post the actual code to this error (i.e. the code around the line 240) - that makes it easier to comment. But in principle the error is telling you, that this is not available inside the lambda - you have to capture it. That means, add this to the parameters inside []. So with @J-Hilk's code it would be:

    QObject::connect(&cntDown, &QTimer::timeout, [this, &msg, &cnt, &cntDown]()->void {

    Regards



  • Alright, thanks to all for you help.


Log in to reply