QT之GUI学习笔记(十九)----QPainter

原文地址:http://devbean.blog.51cto.com/448512/235332
此后讲解内容为QT的2D绘图


一 基本概念

1.
Qt的绘图系统允许使用相同的API在屏幕和打印设备上进行绘制。
整个绘图系统基于QPainter,QPainterDevice和QPaintEngine三个类。

QPainter:用来执行绘制的操作;
QPaintDevice是一个二维空间的抽象,这个二维空间可以由QPainter在上面进行绘制;
QPaintEngine提供了画笔painter在不同的设备上进行绘制的统一的接口。QPaintEngine类用在QPainter和QPaintDevice之间,并且通常对开发人员是透明的,除非你需要自定义一个设备,这时候你就必须重新定义QPaintEngine了。
2. QPainter QPaintDevice QPaintEngine
三者之间的关系如下图所示
这里写图片描述
这种关系的优点:
由于所有的绘制都遵循着同一种绘制流程,
(1)可以很方便的添加新的特性
(2)为不支持的功能添加一个默认的实现方式。
3. QtOpenGL模块
Qt提供了一个独立的QtOpenGL模块
(1)与其他组件的相同之处:可以让你在Qt的应用程序中像使用其他的Qt组件一样使用OpenGL功能
(2)与其他组件的的不同之处:它使用OpenGL作为显示技术,使用OpenGL函数进行绘制

二 代码

1.步骤
Qt的绘图系统的实质:使用QPainter在QPainterDevice上面进行绘制,二者使用QPaintEngine进行通讯。
(1)步骤一:定义一个组件

class PaintedWidget : public QWidget 
{ 
public: 
        PaintedWidget(); 

protected: 
        void paintEvent(QPaintEvent *event); 
};

上段代码定义了一个构造函数,并且重定义paintEvent()函数。

  void paintEvent(QPaintEvent *event);

由函数名称可知该函数是一个事件的回调函数。
一般而言,Qt的事件函数都是protected的,所以,如果你要重写事件,就需要继承这个类了。
(2)步骤二 增加构造函数内的代码
构造函数里面主要是一些大小之类的定义。

PaintedWidget::PaintedWidget() 
{ 
        resize(800, 600); 
        setWindowTitle(tr("Paint Demo")); 
}

(3)步骤三 实现paintEvent()函数

void PaintedWidget::paintEvent(QPaintEvent *event) 
{ 
        QPainter painter(this); 
        painter.drawLine(80, 100, 650, 500); 
        painter.setPen(Qt::red); 
        painter.drawRect(10, 10, 100, 400); 
        painter.setPen(QPen(Qt::green, 5)); 
        painter.setBrush(Qt::blue); 
        painter.drawEllipse(50, 150, 400, 200); 
}

(4)步骤四.显示paintedWidget,并执行函数
main.cpp

int main(int argc, char *argv[]) 
{ 
        QApplication app(argc, argv); 
        PaintedWidget w; 
        w.show(); 
        return app.exec(); 
}

2.所有代码
(1)painter.pro

#-------------------------------------------------
#
# Project created by QtCreator 2017-03-24T21:59:09
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Painter
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += main.cpp\
        paintedwidget.cpp

HEADERS  += paintedwidget.h

INCLUDEPATH+=D:\InstallOpencv\opencvBinary\include\opencv\
             D:\InstallOpencv\opencvBinary\include\opencv2\
             D:\InstallOpencv\opencvBinary\include


LIBS+=  D:\InstallOpencv\opencvBinary\lib\libopencv_bgsegm310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_bioinspired310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_calib3d310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_ccalib310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_core310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_cvv310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_datasets310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_dnn310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_dpm310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_face310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_features2d310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_flann310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_fuzzy310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_highgui310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_imgcodecs310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_imgproc310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_line_descriptor310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_ml310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_objdetect310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_phase_unwrapping310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_photo310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_plot310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_reg310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_rgbd310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_saliency310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_shape310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_stereo310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_stitching310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_structured_light310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_superres310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_surface_matching310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_text310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_tracking310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_video310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_videoio310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_videostab310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_xfeatures2d310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_xobjdetect310.dll.a\
        D:\InstallOpencv\opencvBinary\lib\libopencv_xphoto310.dll.a

用于配置环境
(2)paintedWidget.h

#ifndef PAINTEDWIDGET_H
#define PAINTEDWIDGET_H

#include <QWidget>

class PaintedWidget : public QWidget
{
    Q_OBJECT

public:
    PaintedWidget(QWidget *parent = 0);
    ~PaintedWidget();
protected:
     void paintEvent(QPaintEvent *event);

};

#endif // PAINTEDWIDGET_H

用于表示构造函数的结构

(3)paintedWidget.cpp

#include "paintedwidget.h"
#include<QPainter>
#include<QPaintDevice>
#include<QPaintEngine>
PaintedWidget::PaintedWidget(QWidget *parent)
    : QWidget(parent)
{
    resize(800, 600);
    setWindowTitle(tr("Paint Demo"));
}

PaintedWidget::~PaintedWidget()
{

}
void PaintedWidget::paintEvent(QPaintEvent *event)
{
        QPainter painter(this);
        painter.drawLine(80, 100, 650, 500);
        painter.setPen(Qt::red);
        painter.drawRect(10, 10, 100, 400);
        painter.setPen(QPen(Qt::green, 5));
        painter.setBrush(Qt::blue);
        painter.drawEllipse(50, 150, 400, 200);
}

用于实现构造函数
(4)main.cpp

#include "paintedwidget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    PaintedWidget w;
    w.show();

    return a.exec();
}

3.运行结果
这里写图片描述

三 知识点解释

1.

 QPainter painter(this);

(1)这一行代码声名了一个Qpainter对象。
由于我们在这个函数的栈空间建立了对象,因此不需要delete。
(2)QPainter接收一个QPaintDevice*类型的参数。
QPaintDevice有很多子类,比如QImage和QWidget。
QPaintDevice可以理解成要在哪里去画,而现在我们希望在这个widget上画,因此传入的是this指针。
2.

   //用于绘制直线
   painter.drawLine(80, 100, 650, 500);
  //用于绘制长方形
   painter.drawRect(10, 10, 100, 400);
   //用于绘制椭圆
   painter.drawEllipse(50, 150, 400, 200);

QPainter有很多以draw开头的函数,用于各种图形的绘制。
所有的draw函数如下图所示
draw函数
3.

       painter.setPen(Qt::red);
       painter.setPen(QPen(Qt::green, 5));
       painter.setBrush(Qt::blue);

setPen用于设置画笔;setBrush用于设置画刷。

四 画笔 画刷

Qt绘图系统提供了三个主要的参数设置,画笔(pen)、画刷(brush)和字体(font)。
1. 画笔
(1)画笔是用于绘制线的,比如线段、轮廓线等。
画笔类即QPen,可以设置画笔的样式,画笔的颜色,画笔的转折点样式等。
(2)画笔的样式可以在创建时指定,也可以由setStyle()函数指定。
(3)画笔支持三种主要的样式:笔帽(cap),结合点(join)和线形 (line)。
样式图如下
这里写图片描述
图共分成三行:第一行是Cap样式,第二行是Join样式,第三行是Line样式。QPen允许你使用setCapStyle()、setJoinStyle()和setStyle()分别进行设置。
2.画刷
(1)作用:填充封闭的几何图形
(2)两个参数:颜色和样式。也可使用纹理或者渐变色来填充图形。
(3)不同的画刷样式
这里写图片描述
注意:这些样式也可用通过一个enum进行设置
3.OpenGL是一个状态机,含义是OpenGL保存的只是各种状态。
比如,你把颜色设置成红色,那么,直到你重新设置另外的颜色,它的颜色会一直是红色。
QPainter也是这样,它的状态不会自己恢复,除非你使用了各种set函数。因此,如果在上面的代码中,我们在椭圆绘制之后再画一个椭圆,它的样式还会是绿色5px的轮廓和蓝色的填充,除非你显式地调用了set进行更新。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值