目錄
Qt:繪圖總結
流程圖
主線程主要的工作内容:
繪圖線程主要的工作内容:
Qt:繪圖總結
- 線上實時動态繪圖—雙緩存繪圖法(兩個線程,【主線程】和【繪圖線程】)
流程圖
如下:
關于流程圖的說明:
主線程(QWidget):負責繪圖線程變量的聲明定義及初始化,信号和槽,并将繪圖線程繪制好的圖檔列印在主視窗上。
繪圖線程(QObejct):負責按照要求繪圖,并将繪制好的圖檔傳遞給主視窗。
- 具體程式說明
主線程主要的工作内容:
- 包含必要的頭檔案(QT及繪圖線程的頭檔案)
- 聲明各類指針(1:繪圖線程的指針對象,2:線程指針)
- 在構造函數中,對指針進行初始化【此處要注意,要将指針對象的父類指向線程指針,進行信号和槽的設定(包括各類槽函數和信号的原型聲明及定義),主線程觸發信号,繪圖線程進行繪圖】
- 繪圖線程完成繪圖,發送信号給主線程,并将繪制好的圖檔傳遞給主線程
- 主線程接受到繪圖線程的圖檔後,進行繪制
- 主線程.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
//繪圖線程的頭檔案
#include"imagethread.h"
//線程頭檔案
#include<QThread>
//繪圖需要的頭檔案
#include<QImage>
#include<QPainter>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
protected:
void paintEvent(QPaintEvent *event);
public:
explicit Widget(QWidget *parent = 0);
~Widget();
void stopimage();//關閉image畫圖線程
void getimag(QImage);//接受繪圖線程繪制好的圖檔,并更新繪圖事件
void imagesignal();//啟動繪圖線程繪圖函數的指令
private slots:
...
private:
Ui::Widget *ui;
imagethread *imT;//建立屬于繪圖線程的指針對象
QThread *imgthread;//線程指針
QImage image;//image變量
signals:
void sendimage();//主線程.cpp中有解釋這個型号的作用
};
#endif // WIDGET_H
- 主線程.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
// ui->setupUi(this);//自己寫的ui,就不需要這個了
uiset();
/*****************線程image********************/
imT = new imagethread;//配置設定空間
imgthread = new QThread(this);//指定父對象,子線程
imT->moveToThread(imgthread);//自定義線程加入子線程
//注意:使用moveToThread的對象的父對象必須是QObejct類型
//啟動image子線程
imgthread->start();
//啟動線程繪圖函數的信号和槽,隻有發送sendimage信号時,繪圖線程中真正繪圖的函數才會啟動
connect(this,&Widget::sendimage,imT,&imagethread::drawImage);//發送sendimage,就會啟動線程中的drawimage函數,進行畫圖
connect(imT,&imagethread::updateImage,this,&Widget::getimag);//一旦畫圖線程被調用,就會把畫好的内容回報到傳輸到getimage函數
}
Widget::~Widget()
{
delete ui;
}
//畫圖信号(繪圖線程的啟動)
void Widget::imagesignal()
{
..............
emit sendimage();//啟動繪圖線程的信号,正式進入繪圖線程,進行繪圖
..............
}
//前界面畫圖程式
void Widget::getimag(QImage temp)
{
qDebug()<<"image繪制好的圖檔已經傳輸給widget,完成";
update();//更新paintEvent事件
}
//畫圖事件
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter p(this);//指定對象為視窗
p.drawPixmap(0,0,width(),height(),QPixmap("://image/ubk.png"));//設定背景圖檔
p.drawImage(x,y,image);//起點坐标x和y,之後繪圖線程繪制好的圖檔
}
//關閉線程image
void Widget::stopimage()
{
if(imgthread->isRunning() == true)
//首先判斷線程是否已經關閉,如果關閉請避免多次關閉引發記憶體洩漏
{
imgthread->quit();
imgthread->wait();
}
if(imT!=NULL)//imT不為空,删除,讓他變成空的
{
delete imT;
}
}
注意:使用moveToThread的對象的父對象必須是QObejct類型 子線程的類必須是QObject
繪圖線程主要的工作内容:
- 與主線程信号和槽對應的槽函數的原型聲明及定義
- 将繪制好的圖檔傳回給主線程
- 繪圖線程.h
#ifndef IMAGETHREAD_H
#define IMAGETHREAD_H
#include <QObject>
#include<QPainter>
#include<QImage>
#include<QDebug>
class imagethread : public QObject
{
Q_OBJECT
public:
explicit imagethread(QObject *parent = nullptr);
//線程處理函數
void drawImage();
signals:
//發送信号,把畫好的圖檔進行傳送
void updateImage(QImage temp);
public slots:
};
#endif // IMAGETHREAD_H
繪圖線程.cpp
#include "imagethread.h"
imagethread::imagethread(QObject *parent) : QObject(parent)
{
}
void imagethread::drawImage()
{
QImage image(truesize,truesizeh,QImage::Format_ARGB32);//畫幅大小
//定義畫家,指定繪圖裝置
QPainter p(&image);
................//繪制操作
emit updateImage(image);//将繪制好的圖檔傳送
}