精华内容
下载资源
问答
  • qt 绘图

    2016-01-07 09:48:03
    qt 绘图
    </pre><pre style="margin-top: 0px; margin-bottom: 0px;"><span style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">"widget.h"</span>
    #include "ui_widget.h"
     
    
    #include <QPainter>
     
    
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    }
     
    
    Widget::~Widget()
    {
        delete ui;
    }
     
    
    void Widget::paintEvent(QPaintEvent *event)
    {
     
    
        QPainter painter(this);
        painter.drawLine(QPoint(0,0),QPoint(100,100));
     
    
        //创建画笔绘制虚线
        QPen pen(Qt::green,5,Qt::DotLine,Qt::RoundCap,Qt::RoundJoin);
        painter.setPen(pen);
        QRectF rectangle(70.0,40.0,80.0,60.0);
        int startAngle=30*16;
        int spanAngle=120*16;
        painter.drawArc(rectangle,startAngle,spanAngle);
     
    
        //绘制一个矩形
        pen.setWidth(1);
        pen.setStyle(Qt::SolidLine);
        painter.setPen(pen);\
        painter.drawRect(160,20,50,40);
        //创建画刷
        QBrush brush(QColor(0,0,255),Qt::Dense4Pattern);
        //使用画刷
        painter.setBrush(brush);
        //绘制画刷
        painter.drawEllipse(220,20,50,50);
     
    
     
    
        //设置纹理
        brush.setTexture(QPixmap("yafeilinux.png"));
        //重新使用画刷
        painter.setBrush(brush);
        //定义四个点
        static const QPointF points[4]={
            QPointF(270.0,80.0),
            QPointF(290.0,10),
            QPointF(350.0,30),
            QPointF(390.0,50)
     
    
     
    
        };
        painter.drawPolygon(points,4);
     
    
     
    
        painter.fillRect(QRect(10,100,150,20),QBrush(Qt::darkYellow));
        //删除区域
        //painter.eraseRect(QRect(50,0,50,120));
        //线性渐变
        //这两个点就是为了指定,颜色渐变的方向
        QLinearGradient linearGradient(QPointF(40,190),QPointF(70,190));
     
    
        //插入颜色
        linearGradient.setColorAt(0,Qt::yellow);
        linearGradient.setColorAt(0.5,Qt::red);
        linearGradient.setColorAt(1.0,Qt::green);
     
    
        //指定渐变区域以外的区域的扩散方式
        //QGradient::PadSpread 使用最接近的颜色进行填充(....y, y, r, g, g....)
        //QGradient::ReflectSpread 在渐变区域以外的区域反射渐变(y, r, g, g, r, y)
        //QGradient::RepeatSpread 在渐变区域以外的区域重复渐变(y, r, g, y, r, g)
        linearGradient.setSpread(QGradient::RepeatSpread);
        //使用渐变作为画刷
        painter.setBrush(linearGradient);
        painter.drawRect(10,170,90,40);
        //辐射渐变
        QRadialGradient radialGradient(QPointF(200,190),50,QPointF(275,200));
        radialGradient.setColorAt(0,QColor(255, 255, 100, 150));
        radialGradient.setColorAt(1,QColor(0, 0, 0, 50));
        painter.setBrush(radialGradient);
        painter.drawEllipse(QPointF(200,190),50,50);
     
    
        //锥形渐变
        QConicalGradient conicalGradient(QPointF(350,190),60);
        conicalGradient.setColorAt(0.2,Qt::cyan);
        conicalGradient.setColorAt(0.9,Qt::black);
        painter.setBrush(conicalGradient);
        painter.drawEllipse(QPointF(350,190),50,50);
        //画笔使用线性渐变来绘制直线和文字
        painter.setPen(QPen(linearGradient,2));
        painter.drawLine(0,280,100,280);
        painter.drawText(150,280,tr("helloQt"));
     
    
    }
     
    
    展开全文
  • Qt 绘图

    2017-11-26 09:50:25
    这一节介绍 Qt绘图基础知识,我们都知道,Qt绘图使用的是 QPainter,但是首先需要弄明白:在什么上绘图和在哪里绘图,然后才是怎么绘图,我们就围绕这几个问题来展开。 在什么上绘图 The QPaintDevice ...

    绘图基础

    这一节介绍 Qt 的绘图基础知识,我们都知道,Qt 里绘图使用的是 QPainter,但是首先需要弄明白:在什么上绘图和在哪里绘图,然后才是怎么绘图,我们就围绕这几个问题来展开。

    在什么上绘图

    The QPaintDevice class is the base class of objects that can be painted on with QPainter.

    A paint device is an abstraction of a two-dimensional space that can be drawn on using a QPainter. Its default coordinate system has its origin located at the top-left position. X increases to the right and Y increases downwards. The unit is one pixel.

    The drawing capabilities of QPaintDevice are currently implemented by the QWidget, QImage, QPixmap, QGLPixelBuffer, QPicture, and QPrinter subclasses.

    上面的内容来自于 Qt 的帮助文档,在 QPaintDevice 的子类里用 QPainter 绘图,最常见的就是在 QWidget, QPixmap, QPixture, QPrinter 上面绘图。

    在哪里绘图

    知道了可以在哪些类中绘图了,总不能在这些类的子类中随便写个函数就可以绘图了吧!这需要分情况,例如在 MainWidget 的构造函数里创建一个 QPixmap,并在它上面画图,然后设置为 QLabel 的 pixmap:

          
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
          
    MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent), ui( new Ui::MainWidget) {
    ui->setupUi( this);
    // 创建 pixmap
    pixmap = QPixmap( 100, 100);
    pixmap.fill(Qt::gray);
    QPainter painter(&pixmap);
    painter.drawRect( 10, 10, 80, 80);
    painter.drawText( 20, 30, "Hello World");
    // 使用 pixmap
    ui->label->setPixmap(pixmap);
    }

    在非 widget 上绘图,如上面的 QPixmap,在什么地方都可以,但是在 QWidget 及其子类里绘图却没有这么自由,通常都是要在哪个 widget 上绘图,就需要在它的 paintEvent() 函数里绘图,即重写 paintEvent() 函数。

    例如类 PandoraWidget 是 QWidget 的子类,要在它上面画一个矩形,它的 paintEvent() 函数如下:

          
    1
    2
    3
    4
    5
    6
          
    void PandoraWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this); // this 是 PandoraWidget 的指针
    painter.setPen(Qt::gray);
    painter.setBrush(Qt::green);
    painter.drawRect( 10, 10, 50, 50);
    }

    考虑一个问题,PandoraWidget 上有一个叫 magicLabel 的 QLabel,打算在 magicLabel 上画一个矩形,在 PandoraWidget 的 paintEvent() 函数像下面这样用 magicLabel 构造 QPainter,然后绘图可以吗?

          
    1
    2
    3
    4
    5
    6
          
    void PandoraWidget::paintEvent(QPaintEvent *) {
    QPainter painter(ui->magicLabel); // 注意这里
    painter.setPen(Qt::gray);
    painter.setBrush(Qt::green);
    painter.drawRect( 10, 10, 50, 50);
    }

    运行程序,结果并没有在 magicLabel 上绘制出矩形,而且还输出了下面的错误:

    QWidget::paintEngine: Should no longer be called
    QPainter::begin: Paint device returned engine == 0, type: 1
    QPainter::setPen: Painter not active
    QPainter::setBrush: Painter not active
    QPainter::drawRects: Painter not active

    总是提示 Painter not active,上面提到过:想要在哪个 widget 上绘图,就需要在它的 paintEvent() 函数里绘图,这里的 paintEvent() 函数是 PandoraWidget 的,所以绘图到 PandoraWidget 上成功了,但 paintEvent() 函数不是 QLabel 的,所以企图绘图到 magicLabel 上没成功。

    那是不是就是说,如果想在 magicLabel 上绘图,就必须新创建一个类例如叫 MagicLabel,并且继承自 QLabel,然后在它的 paintEvent() 里绘图?如果有 10 个子 widget,都想在上面画点啥,是不是每个 widget 都要对应创建一个类来实现绘图?我就是想画个圈而已,要创建这么多类也太麻烦了,真的想画个圈圈诅咒 Qt 啊。

    莫急莫急,这里传大家本人秘藏多年的一绝技,就能在 PandoraWidget 的函数里给 magicLabel 绘图了:在事件过滤器 eventFilter() 中拦截 magicLabel 的 QEvent::Paint 事件,用 magicLabel 创建 QPainter,就可以在 magicLabel 上绘图了,上代码,否则估计有人要把我画在圈圈里了:

          
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
          
    PandoraWidget::PandoraWidget(QWidget *parent)
    : QWidget(parent), ui( new Ui::PandoraWidget) {
    ui->setupUi( this);
    ui->magicLabel->installEventFilter( this);
    }
    bool PandoraWidget::eventFilter(QObject *watched, QEvent *event) {
    if (watched == ui->magicLabel && event->type() == QEvent::Paint) {
    magicTime();
    }
    return QWidget::eventFilter(watched, event);
    }
    void PandoraWidget::magicTime() {
    QPainter painter(ui->magicLabel);
    painter.setPen(Qt::gray);
    painter.setBrush(Qt::green);
    painter.drawRect( 10, 10, 50, 50);
    }

    怎么绘图

    下图来自《C++ GUI Programming with Qt 4》,列出了 QPainter 常用的画图方法,都是以 draw 开头,非常直观的列出了绘图函数和绘制出来的图形:

    下面具体的介绍这些函数的使用,它们中很多都有重载的函数,这里只使用其中的一种,其它的用法都差不多,就不一一介绍,需要时查看帮助文档就可以了。

    坐标系

    数学中使用的坐标系是笛卡尔坐标系,X 轴正向向右,Y 轴正向向上。但是,QPainter 也有自己的坐标系,和笛卡尔坐标系有点不一样,原点在 widget 的左上角而不是正中心,X 轴正向向右,Y 轴正向向下。注意: 每个 widget 都有自己独立的坐标系。

    画线 - drawLine()

    给定 2 个点,使用 drawLine() 画一条线。

          
    1
    2
    3
    4
          
    void MainWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.drawLine( 30, 30, 150, 150);
    }

    drawLine() 有什么用?例如可以用来画网格线:

          
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
          
    void GridWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.translate( 30, 30);
    int w = 300;
    int h = 210;
    int gap = 30;
    // 画水平线
    for ( int y = 0; y <= h; y += gap) {
    painter.drawLine( 0, y, w, y);
    }
    // 画垂直线
    for ( int x = 0; x <= w; x += gap) {
    painter.drawLine(x, 0, x, h);
    }
    }

    画多线段 - drawLines()

    给定 N 个点,第 1 和第 2 个点连成线,第 3 和第 4 个点连成线,……,N 个点练成 (N+1)/2 条线,如果 N 是奇数,第 N 个点和 (0,0) 连成线。

          
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
          
    void MultipleLinesWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate( 20, 20);
    static const QPointF points[ 4] = {
    QPointF( 0.0, 100.0),
    QPointF( 20.0, 0.0),
    QPointF( 100.0, 0.0),
    QPointF( 120.0, 100.0)
    };
    painter.drawLines(points, 2); // 4 个点连成 2 条线
    }

    画折线- drawPolyline()

    给定 N 个点,第 1 和第 2 个点连成线,第 2 和第 3 个点连成线,……,第 N-1 和第 N 个点连成线,N 个点共连成 N-1 条线。

          
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
          
    void PolylineWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate( 20, 20);
    static const QPointF points[ 4] = {
    QPointF( 0.0, 100.0),
    QPointF( 20.0, 0.0),
    QPointF( 100.0, 0.0),
    QPointF( 120.0, 100.0)
    };
    painter.drawPolyline(points, 4);
    }

    画多边形 - drawPolygon()

    给定 N 个点,第 1 和第 2 个点连成线,第 2 和第 3 个点连成线,……,第 N-1 和第 N 个点连成线,第 N 个点和第 1 个点连接成线形成一个封闭的多边形。

    drawPolygon() 和 drawPolyline() 很像,但是 drawPolygon() 画的是一个封闭的区域,可以填充颜色,而 drawPolyline() 画的是一些线段,即使它们连成一个封闭的区域也不能填充颜色。

          
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
          
    void PolygonWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate( 20, 20);
    static const QPointF points[ 4] = {
    QPointF( 0.0, 100.0),
    QPointF( 20.0, 0.0),
    QPointF( 100.0, 0.0),
    QPointF( 120.0, 100.0)
    };
    painter.setBrush(Qt::yellow);
    painter.drawPolygon(points, 4);
    }

    可以用 drawPolygon() 来画圆,其实本没有圆,正多边形的边多了,便成了圆,这正是计算机里绘制曲线的原理,插值逼近,在曲线上取 N 个点,点之间用线段连接起来,当 N 越大时,连接出来的图形就越平滑,越接近曲线。

          
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
          
    void PolygonCircleWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing); // 启用抗锯齿效果
    painter.translate(width() / 2, height() / 2); // 把坐标原点移动到 widget 的中心
    painter.setBrush(Qt::lightGray);
    const int COUNT = 10; // 边数,越大就越像圆
    const int RADIUS = 100; // 圆的半径
    QPointF points[COUNT]; // 顶点数组
    for ( int i = 0; i < COUNT; ++i) {
    float radians = 2 * M_PI / COUNT * i; // M_PI 是 QtMath 里定义的,就是 PI
    float x = RADIUS * qCos(radians);
    float y = RADIUS * qSin(radians);
    points[i] = QPointF(x, y);
    }
    painter.drawPolygon(points, COUNT);
    }

    为了介绍方便,数组 points 是在 paintEvent() 里创建的,每次调用 paintEvent() 时都会重新生成一次 points,实际项目里可不能这么做,因为 paintEvent() 会被多次的调用,每次调用都会生成 points。数组 points 只有在必要的时候才重新生成,否则就是浪费计算资源,所以可以放到构造函数里,或者点击按钮改变 COUNT 的值后在对应的槽函数里重新生成 points,然后调用 update() 函数刷新界面。

    画矩形 - drawRect()

    给定矩形左上角的坐标和矩形的长、宽就可以绘制矩形了。

          
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
          
    void MainWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate( 30, 30);
    int x = 0;
    int y = 0;
    int w = 100;
    int h = 100;
    painter.drawRect(x, y, w, h);
    }

    画圆角矩形- drawRoundRect() & drawRoundedRect()

    绘制圆角矩形有 2 个方法:drawRoundRect()drawRoundedRect(),需要给定圆角矩形左上角的坐标、长、宽、圆角的半径。

    当 drawRoundedRect() 中第 7 个参数 Qt::SizeMode 为 Qt::RelativeSize 时,表示圆角半径的单位是百分比,取值范围是 [0, 100],此时 drawRoundedRect() 等价于 drawRoundRect(),其实底层是用这个百分比和对应边长的一半相乘得到圆角的半径(单位是像素)。Qt::SizeMode 为 Qt::AbsoluteSize 时,表示圆角半径的单位是像素。

    有意思的是,在 QSS 中圆角半径大于对应边长的一半,圆角效果就没了,但是使用 drawRoundedRect() 时,圆角的半径大于对应边长的一半时,圆角效果仍然有效,个人认为这个是 QSS 的 bug,但是已经存在很久了。

    下面使用不同的参数绘制了 3 个圆角矩形,便于比较他们之间的异同:

          
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
          
    void RoundRectWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setBrush(Qt::lightGray);
    painter.translate( 30, 30);
    painter.drawRoundRect( 0, 0, 100, 100, 50, 50); // 50%, 50%
    painter.drawRoundedRect( 130, 0, 100, 100, 50, 50, Qt::AbsoluteSize); // 50px, 50px
    painter.drawRoundedRect( 260, 0, 100, 100, 100, 100, Qt::RelativeSize); // 100%, 100%
    }

    画圆、椭圆 - drawEllipse()

    给定椭圆的包围矩形(bounding rectangle),使用 drawEllipse() 绘制椭圆。圆是特殊的椭圆,椭圆有两个焦点,这两个焦点合为一个的时候就是一个正圆了,当包围矩形是正方形时,drawEllipse() 绘制的就是圆。

    当然,画圆的方法很多,上面我们就使用了 drawPolygon(),drawRounedRect() 的方法画圆,不过从语义上来说,用 drawEllipse() 来画圆显得更适合一些。

          
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
          
    void EllipseWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate( 30, 30);
    painter.drawRect( 0, 0, 200, 100); // 椭圆的包围矩形
    painter.setBrush(Qt::lightGray);
    painter.drawEllipse( 0, 0, 200, 100); // 椭圆
    painter.drawEllipse( 230, 0, 100, 100); // 圆
    }

    画弧、弦、饼图 - drawArc()、drawChord()、drawPie()

    画弧使用 drawArc()
    画弦使用 drawChord()
    画饼图用 drawPie()

    把这三个函数放在一起介绍,因为它们的参数都一样,而且 arc, chord, pie 外形也有很多相似之处:

          
    1
    2
    3
          
    void QPainter::drawArc( const QRectF & rectangle, int startAngle, int spanAngle)
    void QPainter::drawPie( const QRectF & rectangle, int startAngle, int spanAngle)
    void QPainter::drawChord( const QRectF & rectangle, int startAngle, int spanAngle)

    • rectangle: 包围矩形
    • startAngle: 开始的角度,单位是十六分之一度,如果要从 45 度开始画,则 startAngle 为 45 * 16
    • spanAngle: 覆盖的角度,单位是十六分之一度
    • 绘制圆心为包围矩形的正中心,0 度在圆心的 X 轴正方向上
    • 角度的正方向为逆时针方向

    下面程序的结果如图:

          
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
          
    void ArcChordPieWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    static int startAngle = 45 * 16; // 开始角度是 45 度
    static int spanAngle = 130 * 16; // 覆盖角度为 130 度
    static QRectF boundingRect(0, 0, 150, 150); // 包围矩形
    painter.translate( 30, 30);
    painter.setBrush(Qt::NoBrush);
    painter.drawRect(boundingRect); // 绘制包围矩形
    painter.setBrush(Qt::lightGray);
    painter.drawArc(boundingRect, startAngle, spanAngle); // 画弧
    painter.translate( 180, 0);
    painter.setBrush(Qt::NoBrush);
    painter.drawRect(boundingRect); // 绘制包围矩形
    painter.setBrush(Qt::lightGray);
    painter.drawChord(boundingRect, startAngle, spanAngle); // 画弦
    painter.translate( 180, 0);
    painter.setBrush(Qt::NoBrush);
    painter.drawRect(boundingRect); // 绘制包围矩形
    painter.setBrush(Qt::lightGray);
    painter.drawPie(boundingRect, startAngle, spanAngle); // 画饼图
    }

    修改 startAngle 和 spanAngle 为负值看看是什么效果。

    绘制 QPixmap - drawPixmap()

          
    1
    2
    3
    4
    5
    6
          
    void MainWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    QPixmap pixmap(":/img/Butterfly.png"); // 从资源文件读取 pixmap
    painter.drawPixmap( 0, 0, pixmap); // 绘制 pixmap
    }

    绘制 QImage - drawImage()

          
    1
    2
    3
    4
    5
    6
          
    void MainWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    QImage image(":/img/Butterfly.png"); // 从资源文件读取 image
    painter.drawImage( 0, 0, image); // 绘制 image
    }

    博文源地址:qtdebug.com/qtbook-paint-base/
    展开全文
  • Qt绘图

    2016-01-24 22:14:03
    Qt绘图系统允许使用相同的API在屏幕和其他打印设备上进行绘制。整个绘图系统基于QPainter,QPaintDevice和QPaintEngine三个类。QPainter用来执行绘制操作;QPaintDevice是一个二维空间抽象,这个二维空间允许...

    本文大部分内容来自于Qt5.5.1的API文档。
    Qt的绘图系统允许使用相同的API在屏幕和其他打印设备上进行绘制。整个绘图系统基于QPainter,QPaintDevice和QPaintEngine三个类。

    QPainter用来执行绘制操作;QPaintDevice是一个二维空间抽象,这个二维空间允许QPainter在上面进行绘制,也就是QPainter的工作空间;QPaintEngine提供了画笔在不同的设备上进行绘制的统一借口。QPaintEngine类应用于QPainter和QPaintDevice,对于开发人员来说一般是透明的,除非你要自定义一个设备,否则不用关心QPaintEngine类。我们可以把QPainter理解成画笔,把QPaintDevice理解成绘制的画纸。QPaintEngine就是让不同的纸张、屏幕可以使用相同的画笔的类。

    我们看一个例子:

    //paintwidget.h
    #ifndef PAINTWIDGET_H
    #define PAINTWIDGET_H
    
    #include <QWidget>
    #include <QPaintEvent>
    #include <QPainter>
    
    class PaintWidget : public QWidget
    {
        Q_OBJECT
    
    public:
        PaintWidget(QWidget *parent = 0);
        ~PaintWidget();
    
    private:
        void paintEvent(QPaintEvent *);
    };
    
    #endif // PAINTWIDGET_H
    //paintwidget.cpp
    #include "paintwidget.h"
    
    PaintWidget::PaintWidget(QWidget *parent)
        : QWidget(parent)
    {
        resize(800, 600);
        setWindowTitle("Paint Demo");
    }
    
    void PaintWidget::paintEvent(QPaintEvent *)
    {
        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);
        painter.save();
    }
    
    PaintWidget::~PaintWidget()
    {
    
    }
    
    //main.cpp
    #include "paintwidget.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        PaintWidget w;
        w.show();
    
        return a.exec();
    }

    代码在paintEvent中创建了一个QPainter对象,每次运行paintEvent时都会创建一个QPainter,这样其实是有问题的,因为QPainter都会被设置。如果设置出现不一致,则会出现屏幕闪动。QPainter对象在需要多次调用不同设置的画笔时,可以使用save()将状态保存下来,后面再使用restore()恢复。一般可以把QPainter作为需要绘制的类的私有成员,这样方便调用。

    paintEvent()是QWidget本身具有的一个virtual protected函数,所以我们可以在子类中重写这个函数。那么paintEvent()是什么时候被调用的呢?Qt文档中描述有三条:1)repaint()或者update()被调用的时候。这样我们可以主动更新界面。2)被其他界面挡住后又恢复过来的时候。比如我们windows中运行上面的代码,在被其他窗口覆盖时会运行一次,然后在此窗口被激活时又会运行一次。

    QPainter有两个构造函数,

    QPainter::QPainter()
    QPainter::QPainter(QPaintDevice * device)

    如果使用第一个方法构造,则需要在后面指定绘图设备,如:

    void MyWidget::paintEvent(QPaintEvent *)
    {
        QPainter p;
        p.begin(this);
        p.drawLine(...);        // drawing code
        p.end();
    }

    QPainter可以画很多几何图形,一般都是调用以draw开头的函数,具体可以参考API。

    QPainter在绘制时按照程序运行的顺序进行绘制,如果出现重叠,则后面绘制的会把前面的覆盖掉。


    QPainter可以使用setPen指定画笔,它有三个重载:

    void QPainter::setPen(const QPen & pen);
    void QPainter::setPen(const QColor & color);
    void QPainter::setPen(Qt::PenStyle style);

    画笔的主要功能是勾勒轮廓线,如果要填充,则需要使用QBrush–画刷。
    QBrush定义了QPainter的填充模式,具有样式、颜色、纹理等特性。画刷的style()定义了填充样式,可以使用Qt::BrushStyle枚举,默认是Qt::NoBrush。具体枚举有:
    Qt::BrushStyle枚举
    画刷的color()可以返回一个当前使用的颜色,setColor()可以设置颜色。画刷的gradient()定义了渐变填充。这个属性只有在填充样式是QLinearGradient, QConicalGradient, 和QRadialGradient或者是继承自QGradient的。如Qt提供的一个例子:

        QRadialGradient gradient(50, 50, 50, 50, 50);
        gradient.setColorAt(0, QColor::fromRgbF(0, 1, 0, 1));
        gradient.setColorAt(1, QColor::fromRgbF(0, 0, 0, 0));
    
        QBrush brush(gradient);

    当画刷样式是Qt::texturePattern时,texture()定义了用于填充的纹理。即使没有设置样式为Qt::texturePattern,当调用setTexture是,QBrush会自动将style()设置为Qt::texturePattern.

    展开全文
  • qt绘图

    2016-04-08 13:44:08
    qt超强精美绘图控件 - QCustomPlot一览 及 安装使用教程

    qt超强精美绘图控件 - QCustomPlot一览 及 安装使用教程

    展开全文
  • Qt 绘图软件

    2015-10-27 22:21:20
    qt 绘图软件
  • curve_QT_qt绘图_QT画布画图_loudqvb.zip
  • QT绘图转换

    2017-11-02 14:50:24
    并不是很完全的QT绘图转换程序,但是可以给对Qt界面编写有障碍的人一点指示
  • Qt绘图源代码

    2017-03-25 15:40:35
    Qt绘图源代码
  • QT 绘图

    2013-03-30 15:57:07
    QT绘图只能在paintEvent中实现吗? 我想实现点击button1就画一条直线,点击button2就画一个矩形。在槽函数中该怎么实现? 比如说我要在button1的槽函数下实现 void button1ClickSlot() { QPainter painter...
  • QT 实时绘图
  • curve_QT_qt绘图_QT画布画图_loudqvb_源码.rar.rar
  • QT绘图程序

    2014-03-25 12:45:24
    QT绘图程序,这是作业培训机构培训课程的项目,对于QT初学者来说是很好的参考资源,我设了十分,不多说,不好不会随便设这么高的分的
  • Qt开发技术:Qt绘图系统(一)绘图系统介绍

    万次阅读 多人点赞 2020-04-14 10:03:30
    若该文为原创文章,未经允许不得转载 原博主博客地址:...本文章博客地址: 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 Qt开发技术:Qt绘图系统(一) ...
  • Qt开发技术:Qt绘图系统(二)QPainter详解

    万次阅读 多人点赞 2020-04-14 10:45:40
    Qt开发技术:Qt绘图系统(二) 前话 红胖子,来也! Qt的图形绘制系统,本篇主要介绍绘图类QPainter。 绘图:QPainter类 概述 QPainter类在窗口和其他绘制设备上执行低级绘制。 QPainter提供高度优化的...
  • QT绘图系统

    2017-11-20 11:35:48
    一、QT绘图原理  Qt4中的2D绘图系统称为Arthur绘图系统,可以使用相同的API在屏幕上和绘图设备上进行绘制,主要基于QPainter、QPainterDevice和 QPainterEngine。QPainter执行绘图操作,QPainterDevice提供...
  • qt绘图教程

    2012-05-07 11:33:04
    qt绘图教程 QPainter 特效 效果
  • Qt绘图基础

    2018-04-22 09:38:52
    Qt绘图的设置 1 QPainter::Antialiasing // 反锯齿 2 QPainter::TextAntialiasing // 文字反锯齿 3 QPainter::SmoothPixmapTransform // 采用平滑的Pixmap变换算法 设置 1 painter.setRenderHint(QPainter::...
  • Qt绘图和绘图设备

    2020-07-12 17:41:10
    Qt绘图系统允许使用相同的API在屏幕和其他打印设备上进行绘制,整个绘图系统基于QPainter,QPainterDevice,QPaintEngine三个类。 QPainter用来执行绘制的操作 QPainterDevice是一个二维空间的抽象,这个二维空间...
  • QT 绘图基础学习

    万次阅读 多人点赞 2018-04-11 09:50:34
    这一节介绍 Qt绘图基础知识,我们都知道,Qt绘图使用的是 QPainter,但是首先需要弄明白:在什么上绘图和在哪里绘图,然后才是怎么绘图,我们就围绕这几个问题来展开。 在什么上绘图 The QPaintDevice ...
  • Qt绘图实现

    2017-12-19 13:46:31
    画线、圆算法自己实现,没有调库,界面是代码完成的,可以不同粗细、颜色;还有一些问题,这个当作第一版吧,可以当作Qt图形学入门的基本框架
  • 本压缩包为利用qt绘图事件与定时器事件制作简易时钟的完整文件,包括头文件,cpp文件以及所用到的时钟背景素材
  • Qt绘图事件

    2020-04-11 10:29:55
    Qt绘图是在绘图事件中完成的。整个绘图系统基于QPainter,QPainterDevice和QPaintEngine三个类。 QPainter是用来绘制的,QPainterDevice是绘图设备,QPainter会把图绘制在QPainterDevice上面。 ...
  • QT绘图系统实例

    2019-04-24 08:05:31
    qt实现绘制,非常实用
  • qt绘图实例

    2013-02-20 15:59:09
    qt是一个大型C++集成块 方便易用。此版本程序有QT4.81开发。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,170
精华内容 6,468
关键字:

qt绘图