Independent Thread

We want to run a single task in an independent thread in a convenient way in some scenarios. It is common in data process and UI interaction event, for example, we want to use QMovie object to play a gif to indicate our software is analyzing test data, the data process workflow must be put in a separated thread to avoid blocking the play of gif file.
Here is a simple demo for the scenarios.
Development environment: C++11, Qt 5.11.2
We created a new thread with a lambda expression to display the task and did other things qDebug() << "Finish Task"; after the thread finished, it's also precise moment to stop our fantasy gif player, right?

int main(int argc, char *argv[])
{
    int a = 1;
    int b = 2;
    QThread *thread = QThread::create( [&a, &b](){
        qDebug() << a+b;
        for( int i = 0; i < 100000; ++i )
        {
            qDebug() << i;
        }
    } );
    thread->start();
    thread->deleteLater();

    while ( !thread->isFinished() ) {
        qDebug() << "not stop";
    }

    thread->wait();
    qDebug() << "Finish Task";
    return 0;
}


Play Gif

In the second part, I play gif file with QMovie and QLabel. They work in UI event loop, if we move the QMovie object to a new thread m_Movie->moveToThread( new QThread() ), the playing process will fail and there is an only static image on the window.

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->pushButton->setCheckable( true );

    m_GifLabel = new QLabel( "Gif", this );
    QSize fatherSize = this->size();
    int w = 400;
    int h = 320;
    int x = static_cast( fatherSize.width() / 2.0 - w / 2.0 );
    int y = static_cast( fatherSize.height() / 2.0 - h / 2.0 );
    m_GifLabel->setGeometry( QRect( x, y, w, h ) );
    m_Movie = new QMovie( "/Users/weiyang/Desktop/ani.gif" );
    m_Movie->setScaledSize( QSize(w, h) );
    m_GifLabel->setMovie( m_Movie );
}

MainWindow::~MainWindow()
{
    delete ui;
    delete m_Movie;
    delete m_GifLabel;
}

void MainWindow::on_pushButton_clicked(bool checked)
{
    int frameCount = m_Movie->frameCount();
    qDebug() << frameCount;

    if( checked )
    {
        m_GifLabel->show();
        m_Movie->start();
    }
    else
    {
        m_Movie->stop();
        m_GifLabel->hide();
    }
}


 


0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You cannot copy content of this page