Why My timer is not emit timeout signal ?



  • if we have a long time to procress some thing, we can use the QProgressDialog to show the schedule. it is very easy and soon if you know the times of your do some thing. like numFiles:

    QProgressDialog progress("Copying files...", "Abort Copy", 0, numFiles, this);
    progress.setWindowModality(Qt::WindowModal);
    
    for (int i = 0; i < numFiles; i++) {
        progress.setValue(i);
    
        if (progress.wasCanceled())
            break;
        //... copy one file
    }
    progress.setValue(numFiles);
    

    According to my want, i subclass QProgressDialog to ProgressDialog, like:

    ProgressDialog::ProgressDialog(const QString &labelText, QWidget *parent):
        QProgressDialog(parent)
    {
        setLabelText(labelText);
        setCancelButtonText(tr("cancel btn"));
    
        setRange(0,100);
    
        setWindowModality(Qt::WindowModal);
    
        /** I want to use the timer to control progress bar value add */
        _t = new QTimer(this);
        _t->setInterval(500);
        connect(_t,&QTimer::timeout,this,&ProgressDialog::StTimeOut);
        _t->start();
    }
    
    void ProgressDialog::StTimeOut()
    {
        int nVal = value();
        qDebug() << "---" << nVal;
        nVal++;
        setValue(nVal);
    }
    

    In Dialog file

    void Dialog::on_btnNoTime_clicked()
    {
        ProgressDialog progress("Copying files...",this);
    
        /** To simulate do long some thing */
        int nSleep = 1000;
        QThread::msleep(nSleep);
        qDebug("Run 1!");
        QThread::msleep(nSleep);
        qDebug("Run 2!");
        QThread::msleep(nSleep);
        qDebug("Run 3!");
        QThread::msleep(nSleep);
        qDebug("Run 4!");
        QThread::msleep(nSleep);
        qDebug("Run 5!");
        QThread::msleep(nSleep);
        qDebug("Run 6!");
        QThread::msleep(nSleep);
        qDebug("Run 7!");
        QThread::msleep(nSleep);
        qDebug("Run 8!");
        QThread::msleep(nSleep);
        qDebug("Run 9!");
        QThread::msleep(nSleep);
        qDebug("Run ok!");
    }
    

    I don't want write timer in Dialog class.

    I want to wrap them in ProgressDialog class, let the interface becomes simple.

    My timer not work.

    Any help is greately appreciated. Thanks.


  • Moderators

    @joeQ said in Why My timer is not emit timeout signal ?:

    QThread::msleep

    It is not working because you're blocking the Qt event loop with all those QThread::msleep calls...



  • @jsulm How to simulate do spend a long time , not block Qt event loop?


  • Moderators

    @joeQ Why do you want to simulate this in the first place? Qt is an event driven framework - you should not do any long lasting calculations in the GUI thread. Move such calculations to other threads - then your UI will not block.



  • @jsulm Ok, you are right. I am wrong.



  • @joeQ said in Why My timer is not emit timeout signal ?:

    @jsulm How to simulate do spend a long time , not block Qt event loop?

    here a quick example, anyway:

    QProgressBar *pbar = new QProgressBar();
    
        pbar->setMaximum(100);
        QTimer *timer = new QTimer();
        timer->setInterval(1000);
        connect(timer, &QTimer::timeout,pbar,[pbar]{pbar->setValue(pbar->value()+1);});
    
        pbar->show();
        timer->start();
    


  • @joeQ said in Why My timer is not emit timeout signal ?:

    How to simulate do spend a long time , not block Qt event loop?

    const int nSleep = 1000;
    QEventLoop delayer;
    QTimer delayTimer;
    delayTimer.setSingleShot(true);
    QObject::connect(&delayTimer,&QTimer::timeout,&delayer,&QEventLoop::quit);
    delayTimer.start(nSleep);
    delayer.exec();
    

    I'm not saying you should use this design though.



  • @VRonin @J-Hilk

    I know ,maybe I am some annoying. But,I have some questions.

    I don't clear QProgressDialog well, How the QProgressDialog was not block gui when QProgressDialog was set Qt::WindowModal ?

    Qt::WindowModal:The window is modal to a single window hierarchy and blocks input to its parent window, all grandparent windows, and all siblings of its parent and grandparent windows.

    I know that, when dialog was set modal show, like:

    {
    QDialog dlg;
    dlg.setModal(true);
    dlg.show(); ///< we know dlg will show bad, it is gui was blocked., if using `QProgressDialog`, is can show well. not have the gui block.
    
    /** spend a long time at here */
    }
    

    what method is used in QProgressDialog? QProgressDialog is in another thread to show ?



  • @joeQ With Qt, anything that is drawn/shown on your screen is handlet in the main GUI-Thread. You can't, without a lot of work, draw/paint anything on your screen outside that main thread.

    To your Modal-Question:

    If you create a Dialog and start it with Exec, the default behaviour is, that a new Window is shown, the Dialoag, and the old Window is disabled, That means the gui will not accept any input from your touchscreen, mouse or keyboard as long as the Dialog is not finished/aborded.

    A modal window is one that blocks input to other windows of your applications. If you set it to NonModal for example, you can than access your other windows while the dialog is up and running.

    This has nothing to do with threads and blocking the GuiThread

    Edit:
    I'll have to rectify myself. IIrc, when you start your QDialog with exec() than that Dialog is indeed started in local event loop.



  • @J.Hilk Thank u, I get it.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.