天天看點

Qt:雙緩存繪圖總結Qt:繪圖總結流程圖主線程主要的工作内容:繪圖線程主要的工作内容:

目錄

Qt:繪圖總結

流程圖

主線程主要的工作内容:

繪圖線程主要的工作内容:

Qt:繪圖總結

  • 線上實時動态繪圖—雙緩存繪圖法(兩個線程,【主線程】和【繪圖線程】)

流程圖

如下:

Qt:雙緩存繪圖總結Qt:繪圖總結流程圖主線程主要的工作内容:繪圖線程主要的工作内容:

關于流程圖的說明:

主線程(QWidget):負責繪圖線程變量的聲明定義及初始化,信号和槽,并将繪圖線程繪制好的圖檔列印在主視窗上。

繪圖線程(QObejct):負責按照要求繪圖,并将繪制好的圖檔傳遞給主視窗。

  • 具體程式說明

主線程主要的工作内容:

  1. 包含必要的頭檔案(QT及繪圖線程的頭檔案)
  2. 聲明各類指針(1:繪圖線程的指針對象,2:線程指針)
  3. 在構造函數中,對指針進行初始化【此處要注意,要将指針對象的父類指向線程指針,進行信号和槽的設定(包括各類槽函數和信号的原型聲明及定義),主線程觸發信号,繪圖線程進行繪圖】
  4. 繪圖線程完成繪圖,發送信号給主線程,并将繪制好的圖檔傳遞給主線程
  5. 主線程接受到繪圖線程的圖檔後,進行繪制
  • 主線程.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

繪圖線程主要的工作内容:

  1. 與主線程信号和槽對應的槽函數的原型聲明及定義
  2. 将繪制好的圖檔傳回給主線程
  • 繪圖線程.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);//将繪制好的圖檔傳送
}