天天看點

54黑馬QT筆記之使用Qt5版本進行線程畫圖

54黑馬QT筆記之使用Qt5版本進行線程畫圖

1 線程繪圖例子

這裡我們使用Qt5版本進行線程繪圖,該例子不算難,步驟就是上一篇文章的步驟。這裡隻需要注意一下,當我們從子線程處理完資料後,通過信号傳參将畫好的資料image傳出來,指派給主線程的image(兩者不一樣),然後當主線程要在視窗繪圖時,必須重寫繪圖事件。

2 代碼

1)自定義類頭檔案:

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QObject>
#include <QImage>

class MyThread : public QObject
{
    Q_OBJECT
public:
    explicit MyThread(QObject *parent = 0);

    //線程處理函數
    void drawImage();

signals:
    void updateImage(QImage temp);

public slots:
};

#endif // MYTHREAD_H

           

2)自定義類.cpp檔案:

#include "mythread.h"
#include <QPainter>
#include <QPen>
#include <QBrush>
#include <QImage>

MyThread::MyThread(QObject *parent) : QObject(parent)
{

}

void MyThread::drawImage()
{
    //定義QImage繪圖裝置
    QImage image(500, 500, QImage::Format_ARGB32);
    //定義畫家,指定繪圖裝置
    QPainter p(&image);


    //定義畫筆對象
    QPen pen;
    pen.setWidth(5); //設定寬度
    //把畫筆交給畫家
    p.setPen(pen);

    //定義畫刷
    QBrush brush;
    brush.setStyle(Qt::SolidPattern); //設定樣式
    brush.setColor(Qt::red); //設定顔色
    //把畫刷交給畫家
    p.setBrush(brush);

    //定義5個點
    QPoint a[] =
    {
       QPoint(qrand()%500, qrand()%500),
       QPoint(qrand()%500, qrand()%500),
       QPoint(qrand()%500, qrand()%500),
       QPoint(qrand()%500, qrand()%500),
       QPoint(qrand()%500, qrand()%500)
    };

    p.drawPolygon(a, 5);


    //通過信号發送圖檔
    emit updateImage(image);

}


           

3)主線程頭檔案:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "mythread.h"
#include <QThread>
#include <QImage>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

    //重寫繪圖事件
    void paintEvent(QPaintEvent *);

    void getImage(QImage); //槽函數
    void dealClose(); //視窗關閉槽函數

private:
    Ui::Widget *ui;
    QImage image;
    MyThread *myT; //自定義線程對象
    QThread *thread; //子線程
};

#endif // WIDGET_H

           

4)主線程.cpp檔案:

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QThread>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //自定義類對象,配置設定空間,不可以指定父對象
    myT = new MyThread;

    //建立子線程
    thread = new QThread(this);

    //把自定義子產品添加到子線程
    myT->moveToThread(thread);

    //啟動子線程,但是,并沒有啟動線程處理函數
    thread->start();

    //線程處理函數,必須通過signal - slot 調用
    connect(ui->pushButton, &QPushButton::pressed, myT, &MyThread::drawImage);
    connect(myT, &MyThread::updateImage, this, &Widget::getImage);

    connect(this, &Widget::destroyed, this, &Widget::dealClose);

}

Widget::~Widget()
{
    delete ui;
}

void Widget::dealClose()
{
    //退出子線程
    thread->quit();
    //回收資源
    thread->wait();
    delete myT;

}

void Widget::getImage(QImage temp)
{
    image = temp;
    update(); //更新視窗,間接調用paintEvent()
}

// 視窗繪圖必須重寫繪圖事件
void Widget::paintEvent(QPaintEvent *)
{
    QPainter p(this); //建立畫家,指定繪圖裝置為視窗
    p.drawImage(50, 50, image);
}

           

5)主函數:正常生成。

6)ui界面:

54黑馬QT筆記之使用Qt5版本進行線程畫圖