Qt多线程绘图并实时刷新画面的方法

⌚Time: 2022-01-15 15:58:32

👨‍💻Author: Jack Ge

多线程绘图方法:

在主线程类里面设置一个QPixmap指针,作为主要画布。


pixmap=new QPixmap(this->size());

pixmap->fill(Qt::white);

主类覆写paintEvent函数


void MainWindow::paintEvent(QPaintEvent *event){

    QPainter painter(this);

    painter.drawPixmap(0,0,*pixmap,0,0,0,0);

}

线程类同样设置QPixmap指针,并且在构造函数接收主线程画布指针


myThread::myThread(QPixmap *pixmap):

    pixmap(pixmap)

{

}

线程类覆写run()方法,实时绘图


void myThread::run(){

    int i=50;

    while(i<100){

        i++;

        QPainter painter(pixmap);

        painter.drawLine(100,i,200,i);

        QThread::msleep(SLEEP_TIME_MS);

    }

}

主线程启动子线程


myThread *m0=new myThread(pixmap);

QThreadPool::globalInstance()->start(m0);

编译运行,应该是一条横线垂直向下移动,逐渐绘制形成一个矩形的动画,但是结果是一条静止的横线

原因是主界面不能够实时刷新图像。用于绘制图像的repaintEvent()函数是在程序初始化时自动调用一次,因此主界面只显示一条静止的横线。解决办法是通过repain()或者update()函数让界面进行实时刷新


实时刷新画面:

方法一:使用信号槽机制在子线程调用主界面的repaint函数

子线程类增加信号rep()


signals:

    void rep();

子线程每次绘图后发射信号


void myThread::run(){

    int i=50;

    while(i<100){

        i++;

        QPainter painter(pixmap);

        painter.drawLine(100,i,200,i);

        QThread::msleep(SLEEP_TIME_MS);

        emit rep();

    }

}

主线程connect函数


connect(m0,SIGNAL(rep()),this,SLOT(repaint()));

方法二:利用定时器实时刷新界面

主线程定义槽函数


protected slots:

    void onTimeOut(){

        repaint();

    }

主线程定义定时器,并且关联槽函数


QTimer *qt0=new QTimer();

qt0->setInterval(REPAINT_TIME);

qt0->start();

connect(qt0,SIGNAL(timeout()),this,SLOT(onTimeOut()));

这样就可以每隔一段时间自动刷新界面

编译运行,成功得到了实时刷新的动态画面