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