Qt繪圖淺析與例項

進擊的汪sir發表於2021-07-16

1. Qt5位置相關函式

Q提供了很多關於獲取窗體位置及顯示區域大小的函式,如x()、y()和pos()、rect()、size()、geometry()等,統稱為“位置相關函式”或“位置函式”。幾種主要位置函式及其之間的區別如圖所示。

image-20210715224140713

具體的相關函式的用法,會在後面的例項中進行講解

2. Qt5基礎圖形的繪製(例項)

繪圖的基本流程,繼承Qwidget類 ,重寫paintEvent函式

這個函式基本寫法如下,註釋已經寫得非常的清楚了

image-20210716092746909

此例項的具體實現包含兩個部分的內容:

一是用於畫圖的區域 PaintArea 類

二是主視窗MainWidget類

image-20210715224506393

paintarea.h 標頭檔案

#ifndef PAINTAREA_H
#define PAINTAREA_H

static int MyBlog = "https://www.cnblogs.com/wanghongyang/"
#include <QWidget>
#include <QPen>
#include <QBrush>

class PaintArea : public QWidget
{
    Q_OBJECT
public:
    enum Shape{Line,Rectangle,RoundRect,Ellipse,Polygon,Polyline,Points,Arc,Path,Text,Pixmap};
    explicit PaintArea(QWidget *parent = 0);
    void setShape(Shape);
    void setPen(QPen);
    void setBrush(QBrush);
    void setFillRule(Qt::FillRule);
    void paintEvent(QPaintEvent *);
    
signals:
    
public slots:
private:
    Shape shape;
    QPen pen;
    QBrush brush;
    Qt::FillRule fillRule;
};

#endif // PAINTAREA_H

解釋:

Qt::FillRule

enum Qt::FillRule,列舉型別

Specifies which method should be used to fill the paths and polygons.

指定應該使用哪個方法來填充路徑和多邊形。

有兩個值

Qt::OddEvenFill 0 Specifies that the region is filled using the odd even fill rule. With this rule, we determine whether a point is inside the shape by using the following method. Draw a horizontal line from the point to a location outside the shape, and count the number of intersections. If the number of intersections is an odd number, the point is inside the shape. This mode is the default.
Qt::WindingFill 1 Specifies that the region is filled using the non zero winding rule. With this rule, we determine whether a point is inside the shape by using the following method. Draw a horizontal line from the point to a location outside the shape. Determine whether the direction of the line at each intersection point is up or down. The winding number is determined by summing the direction of each intersection. If the number is non zero, the point is inside the shape. This fill mode can also in most cases be considered as the intersection of closed shapes.

QPen

The QPen class defines how a QPainter should draw lines and outlines of shapes

QPen類定義了QPainter應該如何繪製線條和形狀的輪廓

QPaintEvent

QPaintEvent類包含繪製事件的事件引數。

The QPaintEvent class contains event parameters for paint events.

PaintArea類的建構函式用於完成初始化工作,設定圖形顯示區域的背景色及最小顯示尺寸,具體程式碼如下:

#include "paintarea.h"
#include <QPainter>
PaintArea::PaintArea(QWidget *parent) :
    QWidget(parent)
{
    setPalette(QPalette(Qt::white));
    setAutoFillBackground(true);
    setMinimumSize(400,400);
}QPalette

QPalette

The QPalette class contains color groups for each widget state.

QPalette類包含每個小部件狀態的顏色組

這裡用到的建構函式

image-20210715231040157

Constructs a palette from the button color. The other colors are automatically calculated, based on this color. Window will be the button color as well.

根據按鈕顏色構造一個調色盤。其他顏色是基於此顏色自動計算的。視窗也將是按鈕的顏色。

setAutoFillBackground(true);

此屬性儲存小部件背景是否自動填充

如果啟用,該屬性將導致Qt在呼叫paint事件之前填充小部件的背景。用的顏色是由小部件調色盤中的QPalette::Window顏色角色定義的。

setShape()函式可以設定形狀,setPen()函式可以設定畫筆,setBrush()函式可以設定畫刷,setFillRule()函式可以設定填充模式,具體程式碼實現如下:

void PaintArea::setShape(Shape s)
{
    shape = s;
    update();
}
static int MyBlog = "https://www.cnblogs.com/wanghongyang/"
void PaintArea::setPen(QPen p)
{
    pen = p;
    update();
}
void PaintArea::setBrush(QBrush b)
{
    brush = b;
    update();
}
void PaintArea::setFillRule(Qt::FillRule rule)
{
    fillRule =rule;
    update();      					//重畫繪製區窗體
}

說一下里面的一些函式和屬性

void QWidget::update()

更新小部件,除非禁用更新或隱藏小部件。

此函式不會導致立即重繪;相反,當Qt返回到主事件迴圈時,它會安排一個油漆事件進行處理。與呼叫repaint()相比,這允許Qt進行優化,以獲得更快的速度和更少的閃爍。

多次呼叫update()通常只會導致一次paintEvent()呼叫。

QWidget::paintEvent(QPaintEvent **event*)

這個事件處理程式可以在子類中重新實現,以接收在event中傳遞的繪製事件。

繪製事件是重新繪製小部件的全部或部分的請求。它的發生有以下原因之一:

  • repaint() or update() was invoked,
  • the widget was obscured and has now been uncovered, or
    many other reasons.

Qt還試圖通過將多個繪製事件合併為一個來加速繪製。當多次呼叫update()或視窗系統傳送多個油漆事件時,Qt將這些事件合併為一個帶有更大區域的事件(參見QRegion::united())。repaint()函式不允許這種優化,所以我們建議儘可能使用update()

update() yyds!!!

  • pen 屬性:是一個QPen物件,用於控制線條的顏色、寬度、線型等,如圖8-1所示矩形邊框的線條的特性就是由pen屬性決定的。
  • brush屬性:是一個QBrush物件,用於設定一個區域的填充特性,可以設定填充顏色、填充方式、漸變特性等,還可以採用圖片做材質填充。
  • font屬性:是一個QFont物件,用於繪製文字時,設定文字的字型樣式、大小等屬性。

PaintArea類的重畫函式程式碼如下:

void PaintArea::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    p.setPen(pen);
    p.setBrush(brush);

    QRect rect(50,100,300,200);

    static const QPoint points[4]=
    {
        QPoint(150,100),
        QPoint(300,150),
        QPoint(350,250),
        QPoint(100,300)
    };
    int startAngle =30*16;
    int spanAngle =120*16;

    QPainterPath path;
    path.addRect(150,150,100,100);
    path.moveTo(100,100);
    path.cubicTo(300,100,200,200,300,300);
    path.cubicTo(100,300,200,200,100,100);
    path.setFillRule(fillRule);

    switch(shape)
    {
        case Line:                                         	//直線
            p.drawLine(rect.topLeft(),rect.bottomRight()); 	break;
        case Rectangle:                                    	//長方形
            p.drawRect(rect);	break;
        case RoundRect:                                    	//圓角方形
            p.drawRoundRect(rect); 	break;
        case Ellipse:                                      	//橢圓形
            p.drawEllipse(rect); 	break;
        case Polygon:                                      	//多邊形
            p.drawPolygon(points,4); 	break;
        case Polyline:                                      //多邊線
            p.drawPolyline(points,4); 	break;
        case Points:                                      	//點
            p.drawPoints(points,4); 	break;
        case Arc:                                          	//弧
            p.drawArc(rect,startAngle,spanAngle);	 break;
        case Path:                                         	//路徑
            p.drawPath(path); 	break;
        case Text:                                        	//文字
            p.drawText(rect,Qt::AlignCenter,tr("Hello Qt!"));	break;
        case Pixmap:                                      	//圖片
            p.drawPixmap(150,150,QPixmap("butterfly.png")); 	break;
        default: 	break;
    }
}

其中

QPainter p(this);
p.setPen(pen);
p.setBrush(brush);

新建一個QPainter物件,然後設定它的畫筆,設定畫刷

QRect rect(50,100,300,200);

設定一個方形區域,為畫長方形、圓角方形、橢圓等做準備。

static const QPoint points[4]-{.….}

建立一個QPoint的陣列,包含四個點,為畫多邊形、多邊線及點做準備。

int startAngle=30*16、int spanAngle =120*16

其中,引數startAngle表示起始角,為弧形的起始點與圓心之間連線與水平方向的夾角;引數spanAngle表示的是跨度角,為弧形起點、終點分別與圓心連線之間的夾角

QPainter類還提供了一個drawPixmap()函式,可以直接將圖片畫到刻畫控制元件上。

QPainterPath

QPainterPath類為繪製操作提供了一個容器,允許構造和重用圖形形狀

利用QPainterPath繪製簡單圖形,QPainterPath類為QPainter類提供了一個儲存容器,裡面包含了所要繪製的內容的集合及繪製的順序,如長方形、多邊形、曲線等各種任意圖形。當需要繪製此預先儲存在QPainterPath物件中的內容時,只需呼叫QPainter類的drawPath()函式即可。

QPainterPath 類提供了許多函式介面,可以很方便地加入一些規則圖形
例如,addRect()函式加入一個方形,addEllipse()函式加入一個橢圓形,addText()函式加入一個字串,addPolygon()函式加入一個多邊形等。同時,QPainterPath類還提供了addPath()函式,用於加入另一個QPainterPath物件中儲存的內容。

3. 主視窗的實現

標頭檔案

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>
#include "paintarea.h"
#include <QLabel>
#include <QComboBox>
#include <QSpinBox>
#include <QPushButton>
#include <QGridLayout>
#include <QGradient>

class MainWidget : public QWidget
{
    Q_OBJECT
    
public:
    MainWidget(QWidget *parent = 0);
    ~MainWidget();
private:
    PaintArea *paintArea;

    QLabel *shapeLabel;
    QComboBox *shapeComboBox;
    QLabel *penWidthLabel;
    QSpinBox *penWidthSpinBox;
    QLabel *penColorLabel;
    QFrame *penColorFrame;
    QPushButton *penColorBtn;
    QLabel *penStyleLabel;
    QComboBox *penStyleComboBox;
    QLabel *penCapLabel;
    QComboBox *penCapComboBox;
    QLabel *penJoinLabel;
    QComboBox *penJoinComboBox;
    QLabel *fillRuleLabel;
    QComboBox *fillRuleComboBox;
    QLabel *spreadLabel;
    QComboBox *spreadComboBox;
    QGradient::Spread spread;
    QLabel *brushStyleLabel;
    QComboBox *brushStyleComboBox;
    QLabel *brushColorLabel;
    QFrame *brushColorFrame;
    QPushButton *brushColorBtn;

    QGridLayout *rightLayout;

protected slots:
    void ShowShape(int);
    void ShowPenWidth(int);
    void ShowPenColor();
    void ShowPenStyle(int);
    void ShowPenCap(int);
    void ShowPenJoin(int);
    void ShowSpreadStyle();
    void ShowFillRule();
    void ShowBrushColor();
    void ShowBrush(int);
};

#endif // MAINWIDGET_H

下面來講解一下

QComboBox

QComboBox小部件是一個組合按鈕和彈出列表

image-20210715234226254

QSpinBox

QSpinBox類提供了一個旋轉框小部件。

image-20210715234349834

接下來看cpp檔案

#include "mainwidget.h"
#include <QColorDialog>
MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    paintArea =new PaintArea;

    shapeLabel =new QLabel(tr("形狀:"));            //形狀選擇下拉選單框
    shapeComboBox =new QComboBox;
    shapeComboBox->addItem(tr("Line"),PaintArea::Line);
    shapeComboBox->addItem(tr("Rectangle"),PaintArea::Rectangle);
    shapeComboBox->addItem(tr("RoundedRect"),PaintArea::RoundRect);
    shapeComboBox->addItem(tr("Ellipse"),PaintArea::Ellipse);
    shapeComboBox->addItem(tr("Polygon"),PaintArea::Polygon);
    shapeComboBox->addItem(tr("Polyline"),PaintArea::Polyline);
    shapeComboBox->addItem(tr("Points"),PaintArea::Points);
    shapeComboBox->addItem(tr("Arc"),PaintArea::Arc);
    shapeComboBox->addItem(tr("Path"),PaintArea::Path);
    shapeComboBox->addItem(tr("Text"),PaintArea::Text);
    shapeComboBox->addItem(tr("Pixmap"),PaintArea::Pixmap);
    connect(shapeComboBox,SIGNAL(activated(int)),this,SLOT(ShowShape (int)));

    penColorLabel =new QLabel(tr("畫筆顏色:"));     	//畫筆顏色選擇控制元件
    penColorFrame =new QFrame;
    penColorFrame->setFrameStyle(QFrame::Panel|QFrame::Sunken);
    penColorFrame->setAutoFillBackground(true);
    penColorFrame->setPalette(QPalette(Qt::blue));
    penColorBtn =new QPushButton(tr("更改"));
    connect(penColorBtn,SIGNAL(clicked()),this,SLOT(ShowPenColor()));

    penWidthLabel =new QLabel(tr("畫筆線寬:"));     	//畫筆線寬選擇控制元件
    penWidthSpinBox =new QSpinBox;
    penWidthSpinBox->setRange(0,20);
    connect(penWidthSpinBox,SIGNAL(valueChanged(int)),this,SLOT (ShowPenWidth(int)));

    penStyleLabel =new QLabel(tr("畫筆風格:"));     	//畫筆風格選擇下拉選單框
    penStyleComboBox =new QComboBox;
    penStyleComboBox->addItem(tr("SolidLine"),static_cast<int>(Qt::SolidLine));
    penStyleComboBox->addItem(tr("DashLine"),static_cast<int>(Qt::DashLine));
    penStyleComboBox->addItem(tr("DotLine"),static_cast<int>(Qt::DotLine));
    penStyleComboBox->addItem(tr("DashDotLine"),static_cast<int>(Qt::DashDotLine));
    penStyleComboBox->addItem(tr("DashDotDotLine"),static_cast<int>(Qt::DashDotDotLine));
    penStyleComboBox->addItem(tr("CustomDashLine"),static_cast<int>(Qt::CustomDashLine));
    connect(penStyleComboBox,SIGNAL(activated(int)),this,SLOT (ShowPenStyle(int)));

    penCapLabel =new QLabel(tr("畫筆頂帽:"));        //畫筆頂端風格選擇下拉選單框
    penCapComboBox =new QComboBox;
    penCapComboBox->addItem(tr("SquareCap"),Qt::SquareCap);
    penCapComboBox->addItem(tr("FlatCap"),Qt::FlatCap);
    penCapComboBox->addItem(tr("RoundCap"),Qt::RoundCap);
    connect(penCapComboBox,SIGNAL(activated(int)),this,SLOT(ShowPenCap (int)));

    penJoinLabel =new QLabel(tr("畫筆連線點:"));     //畫筆連線點風格選擇下拉選單框
    penJoinComboBox =new QComboBox;
    penJoinComboBox->addItem(tr("BevelJoin"),Qt::BevelJoin);
    penJoinComboBox->addItem(tr("MiterJoin"),Qt::MiterJoin);
    penJoinComboBox->addItem(tr("RoundJoin"),Qt::RoundJoin);
    connect(penJoinComboBox,SIGNAL(activated(int)),this,SLOT(ShowPenJoin (int)));

    fillRuleLabel =new QLabel(tr("填充模式:"));    	//填充模式選擇下拉選單框
    fillRuleComboBox =new QComboBox;
    fillRuleComboBox->addItem(tr("Odd Even"),Qt::OddEvenFill);
    fillRuleComboBox->addItem(tr("Winding"),Qt::WindingFill);
    connect(fillRuleComboBox,SIGNAL(activated(int)),this,SLOT (ShowFillRule()));

    spreadLabel =new QLabel(tr("鋪展效果:"));    	//鋪展效果選擇下拉選單框
    spreadComboBox =new QComboBox;
    spreadComboBox->addItem(tr("PadSpread"),QGradient::PadSpread);
    spreadComboBox->addItem(tr("RepeatSpread"),QGradient::RepeatSpread);
    spreadComboBox->addItem(tr("ReflectSpread"),QGradient:: ReflectSpread);
    connect(spreadComboBox,SIGNAL(activated(int)),this,SLOT (ShowSpreadStyle()));

    brushColorLabel =new QLabel(tr("畫刷顏色:"));   	//畫刷顏色選擇控制元件
    brushColorFrame =new QFrame;
    brushColorFrame->setFrameStyle(QFrame::Panel|QFrame::Sunken);
    brushColorFrame->setAutoFillBackground(true);
    brushColorFrame->setPalette(QPalette(Qt::green));
    brushColorBtn =new QPushButton(tr("更改"));
    connect(brushColorBtn,SIGNAL(clicked()),this,SLOT (ShowBrushColor()));

    brushStyleLabel =new QLabel(tr("畫刷風格:"));   	//畫刷風格選擇下拉選單框
    brushStyleComboBox =new QComboBox;
    brushStyleComboBox->addItem(tr("SolidPattern"),static_cast<int>(Qt::SolidPattern));
    brushStyleComboBox->addItem(tr("Dense1Pattern"),static_cast<int>(Qt::Dense1Pattern));
    brushStyleComboBox->addItem(tr("Dense2Pattern"),static_cast<int>(Qt::Dense2Pattern));
    brushStyleComboBox->addItem(tr("Dense3Pattern"),static_cast<int>(Qt::Dense3Pattern));
    brushStyleComboBox->addItem(tr("Dense4Pattern"),static_cast<int>(Qt::Dense4Pattern));
    brushStyleComboBox->addItem(tr("Dense5Pattern"),static_cast<int>(Qt::Dense5Pattern));
    brushStyleComboBox->addItem(tr("Dense6Pattern"),static_cast<int>(Qt::Dense6Pattern));
    brushStyleComboBox->addItem(tr("Dense7Pattern"),static_cast<int>(Qt::Dense7Pattern));
    brushStyleComboBox->addItem(tr("HorPattern"),static_cast<int>(Qt::HorPattern));
    brushStyleComboBox->addItem(tr("VerPattern"),static_cast<int>(Qt::VerPattern));
    brushStyleComboBox->addItem(tr("CrossPattern"),static_cast<int>(Qt::CrossPattern));
    brushStyleComboBox->addItem(tr("BDiagPattern"),static_cast<int>(Qt::BDiagPattern));
    brushStyleComboBox->addItem(tr("FDiagPattern"),static_cast<int>(Qt::FDiagPattern));
    brushStyleComboBox->addItem(tr("DiagCrossPattern"),static_cast<int>(Qt:: DiagCrossPattern));
    brushStyleComboBox->addItem(tr("LinearGradientPattern"),static_cast<int>(Qt:: LinearGradientPattern));
    brushStyleComboBox->addItem(tr("ConicalGradientPattern"),static_cast<int>(Qt:: ConicalGradientPattern));
    brushStyleComboBox->addItem(tr("RadialGradientPattern"),static_cast<int>(Qt:: RadialGradientPattern));
    brushStyleComboBox->addItem(tr("TexturePattern"),static_cast<int>(Qt::TexturePattern));
    connect(brushStyleComboBox,SIGNAL(activated(int)),this,SLOT (ShowBrush(int)));

    rightLayout =new QGridLayout;                   //控制皮膚的佈局
    rightLayout->addWidget(shapeLabel,0,0);
    rightLayout->addWidget(shapeComboBox,0,1);
    rightLayout->addWidget(penColorLabel,1,0);
    rightLayout->addWidget(penColorFrame,1,1);
    rightLayout->addWidget(penColorBtn,1,2);
    rightLayout->addWidget(penWidthLabel,2,0);
    rightLayout->addWidget(penWidthSpinBox,2,1);
    rightLayout->addWidget(penStyleLabel,3,0);
    rightLayout->addWidget(penStyleComboBox,3,1);
    rightLayout->addWidget(penCapLabel,4,0);
    rightLayout->addWidget(penCapComboBox,4,1);
    rightLayout->addWidget(penJoinLabel,5,0);
    rightLayout->addWidget(penJoinComboBox,5,1);
    rightLayout->addWidget(fillRuleLabel,6,0);
    rightLayout->addWidget(fillRuleComboBox,6,1);
    rightLayout->addWidget(spreadLabel,7,0);
    rightLayout->addWidget(spreadComboBox,7,1);
    rightLayout->addWidget(brushColorLabel,8,0);
    rightLayout->addWidget(brushColorFrame,8,1);
    rightLayout->addWidget(brushColorBtn,8,2);
    rightLayout->addWidget(brushStyleLabel,9,0);
    rightLayout->addWidget(brushStyleComboBox,9,1);

    QHBoxLayout *mainLayout =new QHBoxLayout(this);   	//整體的佈局
    mainLayout->addWidget(paintArea);
    mainLayout->addLayout(rightLayout);
    mainLayout->setStretchFactor(paintArea,1);
    mainLayout->setStretchFactor(rightLayout,0);

    ShowShape(shapeComboBox->currentIndex());     		//顯示預設的圖形
}


 shapeComboBox->addItem(tr("Line"),PaintArea::Line): 

QComboBox 的addItem()函式可以僅插入文字,也可同時插入與文字相對應的具體資料,通常為列舉型資料,便於後面操作時確定選擇的是哪個資料。

  penJoinComboBox->addItem(tr("BevelJoin"),Qt::BevelJoin):

選用不同的引數,對應畫筆連線點的不同風格

void MainWidget::ShowPenColor()
{
    QColor color = QColorDialog::getColor(static_cast<int>(Qt::blue));
    penColorFrame->setPalette(QPalette(color));
    int value = penWidthSpinBox->value();
    Qt::PenStyle style = Qt::PenStyle(penStyleComboBox->itemData(penStyleComboBox->currentIndex(),Qt::UserRole).toInt());
    Qt::PenCapStyle cap = Qt::PenCapStyle(penCapComboBox->itemData(penCapComboBox->currentIndex(),Qt::UserRole).toInt());
    Qt::PenJoinStyle join=Qt::PenJoinStyle(penJoinComboBox->itemData(penJoinComboBox->currentIndex(),Qt::UserRole).toInt());

    paintArea->setPen(QPen(color,value,style,cap,join));
}

ShowPenColor()槽函式,利用標準顏色對話方塊QColorDialog獲取所選的顏色,採用QFrame和OPushButton物件組合完成,QFrame物件負責顯示當前所選擇的顏色,QPushButton物件用於觸發標準顏色對話方塊進行顏色的選擇。

在此函式中獲得與畫筆相關的所有屬性值,包括畫筆顏色、畫筆線寬、畫筆風格、畫筆頂帽及畫筆連線點,共同構成QPen物件,並呼叫PaintArea物件的setPen()函式設定PaintArea物件的畫筆屬性

其他的程式碼與這個類似,我就不一一講解,下面列出程式碼

void MainWidget::ShowPenWidth(int value)
{
    QColor color = penColorFrame->palette().color(QPalette::Window);
    Qt::PenStyle style = Qt::PenStyle(penStyleComboBox->itemData(penStyleComboBox->currentIndex(),Qt::UserRole).toInt());
    Qt::PenCapStyle cap = Qt::PenCapStyle(penCapComboBox->itemData(penCapComboBox->currentIndex(),Qt::UserRole).toInt());
    Qt::PenJoinStyle join=Qt::PenJoinStyle(penJoinComboBox->itemData(penJoinComboBox->currentIndex(),Qt::UserRole).toInt());

    paintArea->setPen(QPen(color,value,style,cap,join));
}

void MainWidget::ShowPenStyle(int styleValue)
{
    QColor color = penColorFrame->palette().color(QPalette::Window);
    int value = penWidthSpinBox->value();
    Qt::PenStyle style = Qt::PenStyle(penStyleComboBox->itemData(styleValue,Qt::UserRole).toInt());
    Qt::PenCapStyle cap = Qt::PenCapStyle(penCapComboBox->itemData(penCapComboBox->currentIndex(),Qt::UserRole).toInt());
    Qt::PenJoinStyle join=Qt::PenJoinStyle(penJoinComboBox->itemData(penJoinComboBox->currentIndex(),Qt::UserRole).toInt());

    paintArea->setPen(QPen(color,value,style,cap,join));
}

void MainWidget::ShowPenCap(int capValue)
{
    QColor color = penColorFrame->palette().color(QPalette::Window);
    int value = penWidthSpinBox->value();
    Qt::PenStyle style = Qt::PenStyle(penStyleComboBox->itemData(penStyleComboBox->currentIndex(),Qt::UserRole).toInt());
    Qt::PenCapStyle cap = Qt::PenCapStyle(penCapComboBox->itemData(capValue,Qt::UserRole).toInt());
    Qt::PenJoinStyle join=Qt::PenJoinStyle(penJoinComboBox->itemData(penJoinComboBox->currentIndex(),Qt::UserRole).toInt());

    paintArea->setPen(QPen(color,value,style,cap,join));
}

void MainWidget::ShowPenJoin(int joinValue)
{
    QColor color = penColorFrame->palette().color(QPalette::Window);
    int value = penWidthSpinBox->value();
    Qt::PenStyle style = Qt::PenStyle(penStyleComboBox->itemData(penStyleComboBox->currentIndex(),Qt::UserRole).toInt());
    Qt::PenCapStyle cap = Qt::PenCapStyle(penCapComboBox->itemData(penCapComboBox->currentIndex(),Qt::UserRole).toInt());
    Qt::PenJoinStyle join=Qt::PenJoinStyle(penJoinComboBox->itemData(joinValue,Qt::UserRole).toInt());

    paintArea->setPen(QPen(color,value,style,cap,join));
}

void MainWidget::ShowFillRule()
{
    Qt::FillRule rule = Qt::FillRule(fillRuleComboBox->itemData(fillRuleComboBox->currentIndex(),Qt::UserRole).toInt());
    paintArea->setFillRule(rule);
}

void MainWidget::ShowSpreadStyle()
{
    spread = QGradient::Spread(spreadComboBox->itemData(spreadComboBox->currentIndex(),Qt::UserRole).toInt());
}

void MainWidget::ShowBrushColor()
{
    QColor color = QColorDialog::getColor(static_cast<int>(Qt::blue));
    brushColorFrame->setPalette(QPalette(color));
    ShowBrush(brushStyleComboBox->currentIndex());
}

4. 雙緩衝機制

所謂雙緩衝機制,是指在繪製控制元件時,首先將要繪製的內容繪製在一個圖片中,再將圖片一次性地繪製到控制元件上。

在早期的Qt版本中,若直接在控制元件上進行繪製工作,則在控制元件重繪時會產生閃爍的現象,控制元件重繪頻繁時,閃爍尤為明顯。

雙緩衝機制可以有效地消除這種閃爍現象。自Qt 5版本之後,QWidget 控制元件已經能夠自動處理閃爍的問題。

因此,在控制元件上直接繪圖時,不用再操心顯示的閃爍問題,但雙緩衝機制在很多場合仍然有其用武之地。當所需繪製的內容較複雜並需要頻繁重新整理,或者每次只需要重新整理整個控制元件的一小部分時,仍應儘量採用雙緩衝機制。

5. 雙緩衝機制例項

例項將會在接下來幾篇部落格中給出

6. 參考書籍

《Qt5開發及例項》

相關文章