精华内容
下载资源
问答
  • QPainter
    2021-03-24 17:07:34

    QOpenGLWidget取代了之前的QGLWidget类,用以在Qt中提供OpenGL的编程接口。在QGLWidget类中,我们可以通过方法drawTexture来绘制文本。但是在QOpenGLWidget类的时候,这个方法没有提供了。官方文档给出的建议是混合QPainter使用。本文档就是介绍怎么用QPainter来在OPengl窗口上绘制2D文本、
    最近在用webRTC做直播的时候,需要在视频窗口左边下角显示用户名。视频是yuv420p格式,在QOpenGLWidget中用着色器渲染,用户名的话,用QPanter绘制最为方便。

    一.效果

    这个背景log是一帧yuv图像,用jpg转换而来。用ffmpeg将jpg转换为yuv的指令如下:
    ffmpeg -i Background.jpg -s 400x300 -pix_fmt yuv420p Background.yuv
    转换后用ffplay试下能否正常播放,指令如下:
    ffplay -f rawvideo -video_size 400x300 Background.yuv
    混合渲染的时候有些注意事项,在后文中列出。否则可能会出现文字能正常绘制,但是视频画面为白色的情况。

    二.源码

    ZgVideoOpenGLWidget.h

    #ifndef ZGVIDEOOPENGLWI
    更多相关内容
  • 5.保证无毒 1.简单,方便,实用 3.实例可以自行改用 1.如有非法,本人无法律责任! 8.更多作品,查找标签“朱建强”7.... 4.如需联系我请看左边数字!1.如不知代表何物,那就放弃计算机吧! 0....CSDN老板不让我上传联系方式。
  • 史上最简单实现QPainter以鼠标为中心缩放。拿走不谢
  • 下面小编就为大家带来一篇PyQt5利用QPainter绘制各种图形的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • QPainter

    2020-12-29 18:54:00
    Qt 中提供了强大的 2D 绘图系统,可以使用相同的 API 在屏幕和绘图设备上进行绘制,它主要基于QPainter、QPaintDevice 和 QPaintEngine 这三个类: QPainter 用于执行绘图操作,其提供的 API 在 GUI 或 QImage、...

    概念

    Qt 中提供了强大的 2D 绘图系统,可以使用相同的 API 在屏幕和绘图设备上进行绘制,它主要基于QPainter、QPaintDevice 和 QPaintEngine 这三个类:

    1. QPainter 用于执行绘图操作,其提供的 API 在 GUI 或 QImage、QOpenGLPaintDevice、QWidget 和QPaintDevice 显示图形(线、形状、渐变等)、文本和图像。
    2. QPaintDevice 不直接绘制物理显示画面,而利用逻辑界面的中间媒介。例如,绘制矩形图形时,为了将对象绘制到 QWidget、QGLPixelBuffer、QImage、QPixmap、QPicture 等多种界面中间,必须使用 QPaintDevice。
    3. QPaintEngine 提供了一些接口,可用于 QPainter 在不同的设备上进行绘制。

    绘图系统由 QPainter 完成具体的绘制操作,QPainter 类提供了大量高度优化的函数来完成 GUI 编程所需要的大部分绘制工作。它可以绘制一切想要的图形,从最简单的一条直线到其他任何复杂的图形,例如:点、线、矩形、弧形、饼状图、多边形、贝塞尔弧线等。此外,QPainter 也支持一些高级特性,例如反走样(针对文字和图形边缘)、像素混合、渐变填充和矢量路径等,QPainter 也支持线性变换,例如平移、旋转、缩放。

    QPainter 一般在部件的绘图事件 paintEvent() 中进行绘制,首先创建 QPainter 对象,然后进行图形的绘制,最后记得销毁 QPainter 对象。当窗口程序需要升级或者重新绘制时,调用此成员函数即使用 repaint()和 update() 后,调用函数 paintEvent()。

    paintEvent事件会在什么情况下被调用

    1. 在窗口部件第一次显示时,系统会自动产生一个绘图事件,从而强制绘制这个窗口部件;
    2. 当重新调整窗口部件的大小时,系统也会产生一个绘制事件;
    3. 当窗口部件被其他窗口部件遮挡,然后又再次显示出来的时候,就会对那些隐藏的区域产生一个绘制事件;
    4. 同时也可以调用QWidget::update()或者QWidget::repaint()来强制产生一个绘制事件。二者的区别是:
      1)repaint()函数会强制产生一个即时的重绘事件,而update()函数只是在Qt下一次处理事件时才调用一次绘制事件;
      2)如果多次调用update(),Qt会把连续多次的绘制事件压缩成一个单一的绘制事件,这样可避免闪烁现象。

    用法

    QPainter对象

    QPainter painter;
    

    设置字体-setFont()

    void setFont(const QFont &font);
    QFont font;
    font.setFamily("Consolas"); //款式
    font.setBold(true); //黑体
    font.setPixelSize(40 * ratioH); //大小
    painter.setFont(font);
    

    设置画笔-setPen()

    void setPen(const QPen &pen);
    void setPen(const QColor &color);
    painter.setPen(QColor(0,160,230));
    void setPen(Qt::PenStyle style);
    painter.setPen(Qt::NoPen); //置画笔为空笔 目的是使绘制的图形没有描边
    

    设置画刷-setBrush()

    QBrush brush(QColor::fromRgb(141, 121, 81));
    painter.setBrush(brush);
    

    画圆角矩形

    //QRectF构造一个(x,y)为左上角的坐标,给出宽度,高度的矩形
    void drawRoundedRect ( const QRectF & rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode = Qt::AbsoluteSize )
    //xRadius,yRadius为椭圆的半径
    painter.drawRoundedRect(QRectF(2 * ratioW, 2 * ratioH, width() - 4 * ratioW, height() - 4 * ratioH), rX, rY);
    

    绘制文本
    设置文本两种方式:

    1. 在指定位置绘制文本,不会自动换行
    void QPainter::drawText(int x, int y, const QString &text)
    void QPainter::drawText(const QPoint &position, const QString &text)
    
    1. 在指定的矩形内绘制文本,设置 flags 能够实现自动换行,对齐等
    void QPainter::drawText(const QRect &rectangle, int flags, const QString &text, QRect *boundingRect = 0)
    

    flags 为下面的值之一或则为对其取或的结果:

    Qt::AlignLeft //左对齐
    Qt::AlignRight //右对齐
    Qt::AlignHCenter //水平居中
    Qt::AlignJustify //两端对齐
    Qt::AlignTop //顶部对齐
    Qt::AlignBottom //底部对齐
    Qt::AlignVCenter //垂直居中
    Qt::AlignCenter //居中
    
    void MainWindow::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);
    
        QPainter painter(this);
        // 设置画笔颜色
        painter.setPen(QColor(0, 160, 230));
    
        // 设置字体:微软雅黑、点大小50、斜体
        QFont font;
        font.setFamily("Microsoft YaHei");
        font.setPointSize(50);
        font.setItalic(true);
        painter.setFont(font);
    
        // 绘制文本
        painter.drawText(rect(), Qt::AlignCenter, "Qt");
    }
    

    在这里插入图片描述
    首先为该部件创建了一个 QPainter 对象,用于后面的绘制。
    使用 setPen() 来设置画笔的颜色(淡蓝色)。
    通过使用 QFont 来构建我们想要的字体,setFamily()设置字体为微软雅黑、setPointSize() 设置点大小30、setItalic() 设置斜体, 然后通过 setFont() 来设置字体
    最后调用 drawText() 来实现文本的绘制,这里的 rect() 是指当前窗体的显示区域,Qt::AlignCenter 指文本居中绘制。

    绘制直线

    void MainWindow::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);
    
        QPainter painter(this);
        // 反走样
        painter.setRenderHint(QPainter::Antialiasing, true);
        // 设置画笔颜色
        painter.setPen(QColor(0, 160, 230));
        // 绘制直线
        painter.drawLine(QPointF(0, height()), QPointF(width() / 2, height() / 2));
    }
    

    在这里插入图片描述
    首先我们通过 setRenderHint() 来设置反走样,要么绘制出来的线条会出现锯齿,调用 setPen() 来设置画笔颜色(淡蓝色)。
    最后调用 drawLine() 来实现直线的绘制,其中 QPointF(0, height()) 是指直线的起点坐标、QPointF(width() / 2, height() / 2) 是指直线的终点坐标。

    绘制矩形

    void MainWindow::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);
    
        QPainter painter(this);
    
        // 反走样
        painter.setRenderHint(QPainter::Antialiasing, true);
        // 设置画笔颜色、宽度
        painter.setPen(QPen(QColor(0, 160, 230), 2));
        // 设置画刷颜色
        painter.setBrush(QColor(255, 160, 90));
        painter.drawRect(50, 50, 160, 100);
    }
    

    在这里插入图片描述
    首先我们使用 setPen() 来设置画笔颜色(淡蓝色)、宽度(2 像素),用来设置矩形区域的边框。然后使用setBrush() 来设置画刷颜色(橙色),用来填充矩形区域,最后调用 drawRect() 来实现矩形的绘制,其中参数依次顺序为 x、y、w、h,是指区域从 x 为 50,y 为 50 的坐标点起,宽度为 160,高度为 100 的矩形。

    绘制弧形

    void MainWindow::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);
    
        // 矩形
        QRectF rect(90.0, 90.0, 80.0, 90.0);
        // 起始角度
        int startAngle = 30 * 16;
        // 跨越度数
        int spanAngle = 120 * 16;
    
        QPainter painter(this);
    
        // 反走样
        painter.setRenderHint(QPainter::Antialiasing, true);
    
        // 设置画笔颜色、宽度
        painter.setPen(QPen(QColor(0, 160, 230), 2));
    
        // 绘制弧线
        painter.drawArc(rect, startAngle, spanAngle);
    }
    

    在这里插入图片描述
    画弧线时,角度被分成了十六分之一,就是说,如果要 30 度,就需是 30*16。它有起始角度和跨度,还有位置矩形,所以,要想画出自己想要的弧线,就需要大概估算出各个参数的预估值。

    绘制椭圆

    void MainWindow::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);
    
        QPainter painter(this);
    
        // 反走样
        painter.setRenderHint(QPainter::Antialiasing, true);
    
        // 设置画笔颜色、宽度
        painter.setPen(QPen(QColor(0, 160, 230), 2));
    
        // 绘制椭圆
        painter.drawEllipse(QPointF(120, 60), 50, 20);
    
        // 设置画刷颜色
        painter.setBrush(QColor(255, 160, 90));
    
        // 绘制圆
        painter.drawEllipse(QPointF(120, 140), 40, 40);
    }
    

    在这里插入图片描述
    这里我们绘制了一个椭圆和一个圆形,都是调用 drawEllipse() 接口,我们可以很轻易的发现,如果为椭圆的时候,后面两个参数不一样,圆形则相同。首先我们来看第一个参数 QPointF 是指椭圆的中心点相对当前窗体 QPoint(0, 0) 点的位置,后面的参数指椭圆的 x 轴及 y 轴的半径。

    绘制多边形

    void MainWindow::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);
    
        QPainter painter(this);
    
        // 反走样
        painter.setRenderHint(QPainter::Antialiasing, true);
    
        // 设置画笔颜色
        painter.setPen(QColor(0, 160, 230));
    
        // 各个点的坐标
        static const QPointF points[4] = {QPointF(30, 40), QPointF(60, 150), QPointF(150, 160), QPointF(220, 100)};
    
        // 绘制多边形
        painter.drawPolygon(points, 4);
    }
    

    在这里插入图片描述
    首先,我们定义一个个坐标点的位置,这里有四个点,分别为:QPointF(30, 40)、QPointF(60, 150)、QPointF(150, 160)、 QPointF(220, 100),然后调用 drawPolygon() 将各个点连接起来,绘制为多边形。

    绘制图片

    void MainWindow::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);
    
        QPainter painter(this);
    
        // 反走样
        painter.setRenderHint(QPainter::Antialiasing, true);
    
        // 绘制图标
        painter.drawPixmap(rect(), QPixmap(":/Images/logo"));
    }
    

    在这里插入图片描述
    通过 drawPixmap() 来绘制图片,我们可以指定图片绘制的区域 QRect,这里为整个界面的区域,当界面伸缩的时候,图片也会跟着伸缩。

    反走样
    抗锯齿绘图:又称反走样,对图像的边缘进行平滑处理,使其看起来更加柔和流畅的一种技术.
    QPainter进行绘制时可以使用setRenderHint 渲染提示来指定是否要使用抗锯齿功能。

    QPainter::Antialiasing:指示绘图引擎在可能的情况下应该进行边缘的抗锯齿
    QPainter::TextAntialiasing:绘制的字体抗锯齿

    QT 只是和很多系统的绘图API一样,提供了抗锯齿的方法,不过抗锯齿的属性默认都是关闭的,为了直观的理解抗锯齿(反走样)的作用。我们先给出效果图:
    在这里插入图片描述

    void setRenderHint ( RenderHint hint, bool on = true )
    painter.setRenderHint(QPainter::Antialiasing); //抗锯齿
    

    开启抗锯齿(反走样)功能。
    这里设置Antialiasing属性为true,经过这句设置,我们就打开了反走样功能。QPainter和OPengl一样,是一个状态机。因此,我们这里打开了她,之后所有的代码都是开启反走样绘制的了。

    painter.setRenderHint(QPainter::Antialiasing, true);
    

    关闭反走样功能
    到了这里,我们就会发现,反走样的效果要比走样的好得多。那么为什么系统绘图的API(包含QT在内)为什么默认不打开反走样的呢?这是因为,反走样是一种比较复杂的算法,在一些对图像质量要求不高的应用中,是不需要进行开启反走样的。为了提高效率,一般的图形绘制,都是默认不开启反走样的。

    painter.setRenderHint(QPainter::Antialiasing, false);
    

    示例:
    manwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
     
    #include <QMainWindow>
     
    namespace Ui {
    class MainWindow;
    }
     
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
     
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
        void paintEvent(QPaintEvent *event);
     
    private:
        Ui::MainWindow *ui;
    };
     
    #endif // MAINWINDOW_H
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QPainter>
    #include <QRect>
    #include <QBrush>
    #include <QFont>
    //用到什么类就包含什么头文件
     
    //这个MainWindow类是系统自动为我起的名字,实际操作中可自定义
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
     
    MainWindow::~MainWindow()
    {
        delete ui;
    }
     
    //核心代码
    void MainWindow::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);             // 创建QPainter一个对象
     
        // 画一条直线
        QPen pen;
        pen.setColor(Qt::yellow);           // 设置画笔为黄色
        painter.setPen(pen);                // 设置画笔
        painter.drawLine(rect().topLeft(), rect().bottomRight());
     
        // 画一个空心矩形
        pen.setColor(Qt::darkRed);
        painter.setPen(pen);
        painter.drawRect(QRect(1, 1, 100, 100));
     
        // 画一个实心矩形
        QBrush bruch(Qt::FDiagPattern);     // 画刷
        painter.setBrush(bruch);            // 设置画刷
        painter.drawRect(QRect(105, 1, 100, 100));
     
        // 画一个多点线
        pen.setColor(Qt::white);
        painter.setPen(pen);
        bruch.setStyle(Qt::NoBrush);        // 将画刷设置成null
        painter.setBrush(bruch);
        static const QPointF points[4] = {QPointF(210.0, 1), QPointF(220.0, 50.3), QPointF(300, 100.4), QPointF(260.4, 120.0)};
        painter.drawPolyline(points, 4);
     
        // 画多个点
        QPointF pointf[10];
        for (int i=0; i<10; ++i)
        {
            pointf[i].setX(2.0+i*10.0);
            pointf[i].setY(130.0);
        }
        painter.drawPoints(pointf, 10);
     
        // 画多条线
        QLineF linef[5];
        for (int j=0; j<5; ++j)
        {
            linef[j].setP1(QPointF(110.9+j*10, 120.0));
            linef[j].setP2(QPointF(120.8+j*12, 200.0));
        }
        painter.drawLines(linef, 5);
     
        // 画一个多边形
        QPolygonF polygon;
        polygon << QPointF(200.0, 120.0) << QPointF(230.0, 130.0) << QPointF(260.0, 180.0) << QPointF(200.0, 200.0);
        bruch.setStyle(Qt::CrossPattern);
        painter.setBrush(bruch);
        painter.drawPolygon(polygon, Qt::WindingFill);
     
        // 画一个圆角矩形
        QRectF rectangle(290.0, 110.0, 50, 50);
        bruch.setStyle(Qt::SolidPattern);
        painter.setBrush(bruch);
        painter.drawRoundedRect(rectangle, 20.0, 15.0);
     
        // 画一个QString
        painter.drawText(50, 300, "Hello DevDiv!");
     
        //ps:下面这两个有点绿啊。。。。。。如果挡住了上面的图形的话就把他们两个注释掉吧
        //画一个椭圆
        painter.setRenderHint(QPainter::Antialiasing, true);//启用反走样,告诉QPainter用不同颜色强度绘制边框以减少视觉扭曲,这种扭曲一般
        //会在边框转换为像素的时候发生。由此生成的结果是的到一条平滑的曲线
        painter.setPen(QPen(Qt::black, 12, Qt::DashDotDotLine, Qt::RoundCap));
        painter.setBrush(QBrush(Qt::green, Qt::SolidPattern));
        painter.drawEllipse(80, 80, 400, 240);
     
        //绘制三次贝塞尔曲线
        painter.setRenderHint(QPainter::Antialiasing, true);
        QPainterPath path;
        path.moveTo(80, 320);
        path.cubicTo(200, 80, 320, 80, 480, 320);
        painter.setPen(QPen(Qt::black, 8));
        painter.drawPath(path);
    }
    

    main.cpp

    #include "mainwindow.h"
    #include <QApplication>
     
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
     
        return a.exec();
    }
    

    QPainterPath类可以通过连接基本的图形元素来确定任意的矢量形状:直线,椭圆,多边形,弧形,贝塞尔曲线和其他的绘制路径。绘制路径是基本的图元,从这个意义上来说,任何图形或图形组合都可以用绘制路径描述。

    路径可以确定一个边缘,由边缘锁定的区域可以用画刷来填充。在现代应用中,渐变填充已成为单色填充的流行替代品。渐变填充利用颜色插值使得两个或更多颜色之间平滑过渡。他们常被用来创建三维效果,Plastique和Ckeanlooks风格就是使用渐变来渲染QPushButton的。

    QT支持三种类型的渐变:线性渐变、锥形渐变和辐射渐变,下面是例子:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QPainter>
    #include <QPen>
    #include <QBrush>
    #include <QFont>
     
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
     
    MainWindow::~MainWindow()
    {
        delete ui;
    }
     
    void MainWindow::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);//没有使用event,去掉之后会有警告
     
        QPainter painter(this);//下面三个渐变位置重叠了,注意及时注释以看到所有效果
     
        //线性渐变
        // 反走样
        painter.setRenderHint(QPainter::Antialiasing, true);
        // 设置渐变色
        QLinearGradient linear(QPointF(80, 80), QPointF(150, 150));
        linear.setColorAt(0, Qt::black);
        linear.setColorAt(1, Qt::white);
        // 设置显示模式
        linear.setSpread(QGradient::PadSpread);
        // 设置画笔颜色、宽度
        painter.setPen(QPen(QColor(0, 160, 230), 2));
        // 设置画刷填充
        painter.setBrush(linear);
        // 绘制椭圆
        painter.drawRect(QRect(40, 40, 180, 180));
     
     
        //锥形渐变
        // 反走样
        painter.setRenderHint(QPainter::Antialiasing, true);
        // 设置渐变色
        QRadialGradient radial(110, 110, 50, 130, 130);
        radial.setColorAt(0, Qt::black);
        radial.setColorAt(1, Qt::white);
        // 设置显示模式
        radial.setSpread(QGradient::ReflectSpread );
        // 设置画笔颜色、宽度
        painter.setPen(QPen(QColor(0, 160, 230), 2));
        // 设置画刷填充
        painter.setBrush(radial);
        // 绘制椭圆
        painter.drawRect(QRect(40, 40, 180, 180));
     
        //辐射渐变
        // 反走样
        painter.setRenderHint(QPainter::Antialiasing, true);
        // 设置渐变色
        QConicalGradient conical(110, 110, 45);
        conical.setColorAt(0, Qt::black);
        conical.setColorAt(1, Qt::white);
        // 设置画笔颜色、宽度
        painter.setPen(QPen(QColor(0, 160, 230), 2));
        // 设置画刷填充
        painter.setBrush(conical);
        // 绘制椭圆
        painter.drawRect(QRect(40, 40, 180, 180));
    }
    

    目前,我们提到了画笔、画刷和字体设置,另外QPainter还有其他影响图形和文字的绘制方式设置,这里简单提及一点:
    当背景模式是Qt::QpaqueMode时,背景画刷可以用来填充几何图形的背景、文字或者位图

    展开全文
  • 本资源主要用QPainter类绘制直线、矩形、图片基本用法,可以用于自定义QWidget和重新绘制QWidget边框,也就是用这个代码类,可以自定义自己的边框和任意背景形状。原理讲解博客地址:...
  • QT 绘制矩形,圆,椭圆,抠图,截图,QLabel显示,QPainter绘图,绝对好用,很有参考价值
  • 利用 QPainter实现雷达图(玫瑰图)======
  • Qt5气泡式聊天框——QListWidget+QPainter。 气泡式聊天的显示是由QListWidget作为控件,每个气泡是由QListWidgetItem提升成QWidget来实现的。每个气泡可以理解为可以自由布置里面内容的QWidget。每个Item保存聊天的...
  • Qt案例之利用QPainter实现自定义圆形进度条,纯QPainter绘制,不包括图片,详情可参考文章:https://blog.csdn.net/didi_ya/article/details/124378255
  • 因为事件过滤器的影响 无法直接使用QPainter类在子控件上实现画图操作,需使用eventFilter函数进行修改
  • 主要为大家详细介绍了使用QPainter画一个3D正方体,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 本资源主要用QPainter类绘制直线、矩形、图片基本用法,可以用于自定义QWidget和重新绘制QWidget边框,也就是用这个代码类,可以自定义自己的边框和任意背景形状。原理讲解博客地址:...
  • 随机生成一组数据,QT用Qpainter绘制实时曲线图最简单的折线图
  • Pyqt5 Qpainter绘制基础图形
  • 5.保证无毒 1.简单,方便,实用 3.实例可以自行改用 1.如有非法,本人无法律责任! 8.更多作品,查找标签“朱建强”7.... 4.如需联系我请看左边数字!1.如不知代表何物,那就放弃计算机吧! 0....CSDN老板不让我上传联系方式。
  • QT QPainter

    2021-06-17 22:54:55
    QPainter类在小部件和其他绘制设备上执行低级绘制。 QPainter提供了高度优化的功能来完成大多数图形GUI程序所需的工作。它可以画从简单的线条到复杂的形状,如馅饼和和弦。它还可以绘制对齐的文本和像素图。通常,它...

    1.概览

    QPainter类在widgets和其他绘图设备上执行低级的绘制。
    QPainter提供了高度优化的功能来完成大多数图形GUI程序所需的工作。它可以画从简单的线条到复杂的形状,如饼状与和弦。它还可以绘制对齐的文本和像素图。通常,它会绘制一个“自然”坐标系,但也可以进行视图和视角的变换。QPainter可以对继承QPaintDevice类的任何对象进行操作。
    QPainter的常见用法是在widgets的paintEvent函数中:构造和自定义一个(例如设置笔或笔刷)painter对象,然后画图。请记住在绘制后销毁QPainter对象。例如:

    void SimpleExampleWidget::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        painter.setPen(Qt::blue);
        painter.setFont(QFont("Arial", 30));
        painter.drawText(rect(), Qt::AlignCenter, "Qt");
    }

    QPainter的核心功能是绘图,但该类还提供了几个函数,允许您自定义QPainter的设置及其渲染质量,以及其他启用剪裁的函数。此外,您还可以通过指定QPainter的构图模式来控制不同形状如何合并在一起。

    isActive()函数的作用是:指示painter是否处于活动状态。painter由begin()函数和接受QPaintDevice参数的构造函数激活。end()函数和析构函数将其停用。

    QPainter与QPaintDevice和QPaintEngine类一起构成了Qt油漆系统的基础。QPainter是用于执行绘图操作的类。QPaintDevice表示可以使用QPainter在其上绘制的设备。QPaintEngine提供了一个接口,painter可以使用这个接口来绘制不同类型的设备。如果painter处于活动状态,device()返回painter在其上绘制的绘制设备,paintEngine()返回painter当前正在操作的绘制引擎。

    有时,让别人在一个不寻常的QPaintDevice上画画也是可以的,QPainter有一个静态函数来实现这个功能,setRedirected()。

    警告:当paintdevice是一个widget时,QPainter只能在paintEvent()函数或由paintEvent()调用的函数中使用。

    2.设置

    你可以根据您的偏好自定义QPainter,然后进行绘制:

    • font():是用于绘制文本的字体。如果QPainter是active(),你可以分别使用fontInfo()和fontMetrics()函数来检索当前设置的字体及其指标的信息。
    • brush():定义用于填充形状的颜色或图案。
    • pen():定义用于绘制线条或边界的颜色或点。
    • backgroundMode():定义是否存在background(),即Qt::OpaqueMode或Qt::TransparentMode。
    • background():仅适用于backgroundMode()为Qt::OpaqueMode且pen()为点画。在这种情况下,它描述了点画中背景像素的颜色。
    • brushOrigin():定义了平铺画笔的起源,通常是小部件背景的起源。
    • viewport(), window(), worldTransform()组成了QPainter的坐标转换系统。有关更多信息,请参阅坐标转换部分和坐标系统文档。
    • hasClipping():告诉我们QPainter是否在剪辑,如果QPainter在剪辑,它将剪辑到clipRegion()。
    • layoutDirection():定义绘制文本时QPainter使用的布局方向。
    • worldMatrixEnabled():表示是否启用世界转换。
    • viewTransformEnabled():告诉是否启用视图转换。

    请注意,其中一些设置镜像了一些绘制设备的设置,例如QWidget::font()。QPainter::begin()函数(或等效的QPainter构造函数)从绘制设备复制这些属性。

    你可以在任何时候通过调用save()函数来保存QPainter的状态,save()函数将所有可用的设置保存在一个内部堆栈中。restore()函数将它们弹出。

    3.绘图

    QPainter提供了绘制大多数基本图形元素的函数:drawPoint(), drawPoints(), drawLine(), drawRect(), drawRoundedRect(), drawEllipse(), drawArc(), drawPie(), drawChord(), drawPolyline(), drawPolygon(), drawConvexPolygon()和drawCubicBezier()。两个方便的函数,drawRects()和drawLines(),使用当前钢笔和画笔在给定的QRects或QLines数组中绘制给定数量的矩形或线条。

    QPainter类还提供了fillRect()函数,它用给定的QBrush填充给定的QRect,以及eras直立()函数,它擦除给定矩形内的区域。

    所有这些函数都有整数和浮点数版本。

    如果您需要绘制一个复杂的形状,特别是如果您需要反复这样做,考虑创建一个QPainterPath并使用drawPath()绘制它。

    QPainter还提供了fillPath()函数,该函数用给定的QBrush填充给定的QPainterPath,以及strokePath()函数绘制给定路径的轮廓(即描边路径)。

    也请参阅矢量变形的例子,它展示了如何使用先进的矢量技术来使用QPainterPath绘制文本,梯度的例子,它显示了Qt中可用的不同类型的梯度,Path stroke示例展示了Qt的内置破折号模式,并展示了如何使用自定义模式来扩展可用模式的范围。

    文本绘制是使用drawText()完成的。当您需要细粒度的定位时,boundingRect()会告诉您给定的drawText()命令将在哪里绘制。


    4.绘制位图和图片

    有绘制像素图/图像的函数,即drawPixmap(), drawImage()和drawTiledPixmap()。drawPixmap()和drawImage()都产生相同的结果,除了drawPixmap()在屏幕上更快,而drawImage()可能在QPrinter或其他设备上更快。

    有一个drawPicture()函数,它绘制整个QPicture的内容。drawPicture()函数是唯一忽略所有painter设置的函数,因为QPicture有自己的设置。


    5.绘制高分辨率的位图和图片

    高分辨率版本的像素图的设备像素比值大于1(参见QImageReader, QPixmap::devicePixelRatio())。如果它与底层QPaintDevice的值匹配,则直接将其绘制到设备上,不应用任何额外的转换。
    例如,在高DPI屏幕上绘制64x64像素大小的QPixmap,设备像素比为2,而设备像素比也为2。请注意,像素图在用户空间中实际上是32x32像素。Qt中基于位图大小计算布局几何的代码路径将使用此大小。这样做的净效果是,位图显示为高DPI的位图,而不是大的位图。

    RenderHint枚举指定了QPainter的标志,这些标志可能被任何给定的引擎所遵守,也可能不被遵守。QPainter::Antialiasing表示引擎应该在可能的情况下消除原语的边缘,QPainter::TextAntialiasing表示引擎应该在可能的情况下消除文本,QPainter::SmoothPixmapTransform表示引擎应该使用一个平滑的像素图转换算法。


    renderHints()函数的作用是:返回一个标志,该标志指定为该画家设置的渲染提示。使用setRenderHint()函数设置或清除当前设置的RenderHints。

    6.坐标变换

    通常,QPainter在设备自己的坐标系(通常是像素)上操作,但QPainter对坐标转换有很好的支持。

    最常用的转换是缩放、旋转、平移和剪切。使用scale()函数按给定的偏移量缩放坐标系统,rotate()函数顺时针旋转坐标系统,translate()函数平移坐标系统(即为点添加一个给定的偏移量)。您还可以使用shear()函数围绕原点扭曲坐标系统。关于剪切坐标系统的可视化,请参阅仿射变换示例。
    请参见转换示例,该示例显示了转换如何影响QPainter渲染图形原语的方式。特别地,它显示了转换的顺序如何影响结果。

    所有的转换操作都作用于转换worldTransform()。矩阵将平面上的一点变换为另一点。有关转换矩阵的更多信息,请参阅Coordinate System和QTransform文档。

    setWorldTransform()函数可以替换或添加到当前设置的worldTransform()。resetTransform()函数重置任何使用translate()、scale()、shear()、rotate()、setWorldTransform()、setViewport()和setWindow()函数进行的转换。deviceTransform()返回一个矩阵,该矩阵将平台依赖的绘制设备的逻辑坐标转换为设备坐标。只有在平台相关句柄上使用平台绘制命令时才需要后一个函数,而且平台本身不进行转换。

    当使用QPainter绘图时,我们使用逻辑坐标指定点,然后将这些点转换为绘图设备的物理坐标。逻辑坐标到物理坐标的映射是由QPainter的combinedTransform()处理的,它是viewport()、window()和worldTransform()的组合。viewport()表示指定任意矩形的物理坐标,window()用逻辑坐标描述相同的矩形,worldTransform()与转换矩阵相同。
    参见坐标系

    7.剪辑

    QPainter可以剪切任何绘图操作到一个矩形,一个区域,或矢量路径。当前的剪辑可以使用函数clipreregion()和clipPath()。路径还是区域是首选(更快)取决于底层的paintEngine()。例如,QImage绘制引擎优先选择路径,而X11绘制引擎优先选择区域。设置剪辑在画家的逻辑坐标中完成。
    在QPainter剪切之后,油漆装置也可以剪切。例如,大多数小部件会夹掉子部件使用的像素,大多数打印机会夹掉纸张边缘附近的一块区域。这个额外的剪切不会反映在clipreregion()或hasClipping()的返回值中。


    8.合成模式

    QPainter提供了CompositionMode枚举,它定义了数字图像合成的Porter-Duff规则;它描述了一个模型,用于将一个图像(源图像)中的像素与另一个图像(目标图像)中的像素相结合。
    两种最常见的组合形式是Source和SourceOver。源用于在绘制设备上绘制不透明对象。在这种模式下,源中的每个像素替换目标中的相应像素。在SourceOver组合模式中,源对象是透明的,并绘制在目标的顶部。
    注意,合成变换是按像素进行的。因此,使用图形原语本身和它的边界矩形之间有一个区别:边界矩形包含alpha == 0的像素(即围绕原语的像素)。这些像素将覆盖其他图像的像素,有效地清除那些,而原语只覆盖自己的区域。

    9.局限性

    如果你正在使用Qt的基于栅格的绘图引擎的坐标,需要注意的是,虽然可以使用大于+/- 215的坐标,但任何在这个范围之外的坐标执行的绘图都不能保证显示出来;这幅图可以剪掉。这是由于在实现中使用了短int。
    Qt的描边器生成的轮廓在处理曲线形状时只是一个近似。在大多数情况下,用另一个bezier曲线段来表示一个bezier曲线段的轮廓是不可能的,因此Qt通过使用几个较小的曲线来近似曲线轮廓。出于性能原因,Qt对这些轮廓使用的曲线数量是有限制的,因此当使用较大的钢笔宽度或缩放时,轮廓误差会增加。为了生成带有较小错误的轮廓,可以使用QPainterPathStroker类,该类具有setCurveThreshold成员函数,让用户指定容错性。另一个解决方法是先将路径转换为多边形,然后再绘制多边形。

    10.性能

    QPainter是一个丰富的框架,它允许开发者进行各种各样的图形操作,比如渐变、组合模式和矢量图形。QPainter可以通过各种不同的硬件和软件栈实现这一点。自然地,硬件和软件的潜在组合对性能有一些影响,确保每一个操作与所有组合模式、笔刷、剪切、转换等的各种组合相结合是快速的,因为排列的数量几乎是不可能的任务。作为一种折衷,我们选择了QPainter API和后端的一个子集,其中的性能可以保证在给定的硬件和软件组合下,我们可以得到尽可能好的性能。

    作为高性能引擎,我们关注的后端是:

    • 栅格——这个后端在纯软件中实现了所有的渲染,并且总是用于渲染QImages。为了优化性能,只使用格式类型QImage:: format_argb32_premultiplying, QImage::Format_RGB32或QImage::Format_RGB16。任何其他格式,包括QImage::Format_ARGB32,性能都要差得多。该引擎默认用于QWidget和QPixmap。
    • OpenGL 2.0 (ES) ——这个后端是硬件加速图形的主要后端。它可以在支持OpenGL 2.0或OpenGL/ES 2.0规范的台式机和嵌入式设备上运行。这包括过去几年生产的大多数显卡。引擎可以通过在QOpenGLWidget上使用QPainter来启用。

    这些操作是:

    • 简单的转换,意味着平移和缩放,加上0,90,180,270度旋转。
    • drawPixmap()结合简单的转换和不透明度与非平滑转换模式(QPainter::SmoothPixmapTransform不启用作为渲染提示)。
    • 矩形填充与纯色,双色线性梯度和简单的变换。
    • 矩形剪辑与简单的转换和相交剪辑。
    • 组合模式QPainter::CompositionMode_Source和QPainter::CompositionMode_SourceOver
    • 圆角矩形填充使用纯色和双色线性梯度填充。
    • 3个x3补丁pixmaps,通过qDrawBorderPixmap。

    这个列表指出了在性能至关重要的应用程序中安全使用哪些特性。对于某些设置,其他操作可能也很快,但在广泛使用它们之前,建议在软件最终将运行的系统上对它们进行基准测试和验证。也有一些情况下,可以使用昂贵的操作,例如结果缓存在QPixmap中。
    参见QPaintDevice、QPaintEngine、Qt SVG、基本绘图示例和绘图实用程序函数。

    展开全文
  • QPainter文本转BMP32,QImage已经保存BMP图片已经不支持32位深的了,自动降到24位深,自己组织BMP信息保存成bmp32的图片
  • QPainter实现Qt5气泡式聊天框,这个QWidget主要是显示一个头像+气泡,气泡里面是聊天的内容等。 气泡是在paintEvent事件中,采用QPainter来绘制的。
  • QPainter详解

    万次阅读 多人点赞 2021-04-29 13:16:29
    1、QPainter类在小部件和其他绘制设备上执行低级绘制。 2、QPainter提供了高度优化的功能来完成大多数图形GUI程序所需的工作。它可以画从简单的线条到复杂的形状。它还可以绘制对齐的文本和像素图。QPainter可以对...

    一、描述

    1、QPainter类在小部件和其他绘制设备上执行低级绘制。

    2、QPainter提供了高度优化的功能来完成大多数图形GUI程序所需的工作。它可以画从简单的线条到复杂的形状。它还可以绘制对齐的文本和像素图。QPainter可以对继承QPaintDevice类的任何对象进行操作。

    3、QPainter与QPaintDeviceQPaintEngine类一起构成了Qt绘制系统的基础。QPainter是用于执行绘图操作的类。QPaintDevice表示可以使用QPainter在其上绘制的设备。QPaintEngine提供了一个接口,画家可以使用这个接口来绘制不同类型的设备。

    二、类型成员

    1、QPainter::CompositionMode。图像合成支持的模式。从实用的角度来看,默认的设置是最好的设置。官方有个“Composition Modes”例子展示了各种模式的效果。

    2、QPainter::PixmapFragmentHint

    • QPainter::OpaqueHint。指示要绘制的pixmap片段是不透明的。不透明碎片可能会更快地绘制。

    3、QPainter::RenderHint。指定QPainter的标志,绘制引擎可能会或不会遵守这些标志。

    • Antialiasing:图像边缘抗锯齿。
    • TextAntialiasing:文本抗锯齿。要强行禁用文本的抗锯齿功能,请不要设置:
        setRenderHint(QPainter::TextAntialiasing, false);

    而是应该在字体的样式策略上设置:

        auto font = this->font();
        font.setStyleHint(font.styleHint(),QFont::NoAntialias);
    • SmoothPixmapTransform:指示引擎应使用平滑pixmap变换算法绘制图片。
    • LosslessImageRendering:尽可能使用无损图像渲染。目前,此提示仅在使用QPainter通过QPrinter或QPdfWriter输出PDF文件时使用。

    三、实用成员函数

    1、QPainter(QPaintDevice *device)

    构造一个立即开始绘制绘制设备的QPainter对象。此构造函数对于临时的绘制者很方便,并且应该只使用一次。构造函数自动调用begin(),QPainter析构函数自动调用end()。

    以下代码效果一样:

         QPainter p;
         p.begin(this);
         p.drawLine(...);
         p.end();
         QPainter p(this);
         p.drawLine(...);

    2、bool begin(QPaintDevice *device)

    开始绘制绘画设备,如果成功则返回true,否则返回false。请注意,在调用begin()时,所有绘画工具设置(setPen(),setBrush()等)都将重置为默认值。

    调用此函数可能存在的错误:

     painter->begin(nullptr); //错误,绘制设备为空
    
     QPixmap image(0, 0);
     painter->begin(&image); //错误,图片为空
    
     painter->begin(myWidget);
     painter2->begin(myWidget); //错误,同一时间不能由两个QPainter绘制同一设备

    注:不支持在格式为QImage::Format_Indexed8QImage上绘制。

    3、QRectF boundingRect(const QRectF &rectangle, int flags, const QString &text)

    返回使用当前设置的font()使用指定标志在给定矩形内部绘制时显示的文本的边界矩形;即该函数告诉您在给定相同参数的情况下drawText()函数将在何处绘制。如果使用指定的标志文本不适合给定的矩形,则该函数返回所需的矩形。flags参数见下面的第30点。

    void Widget::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);
        painter.setPen(QPen(Qt::red,5));
        QRect rect = QRect(20,20,100,50);
        painter.drawRect(rect);
        QFont font = this->font();
        font.setPointSize(30);
        painter.setFont(font);
        painter.drawText(rect,Qt::AlignHCenter | Qt::TextWordWrap,"黄河之水天上来");
        painter.setPen(QPen(Qt::green,5));
        auto bRect = painter.boundingRect(rect,Qt::AlignHCenter | Qt::TextWordWrap,"黄河之水天上来");
        painter.drawRect(bRect);
    }

    红框是设置的要绘制的矩形。不过字太大了只能绘制两个字,绿色是要绘制这句诗实际上需要的边界矩形。

    4、QPoint brushOrigin()

    获取绘制开始的点。

        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing,true);
        painter.setPen(QPen(Qt::red,5));
        painter.drawEllipse(painter.brushOrigin(),5,5);
        painter.translate(50,50);
        painter.drawEllipse(painter.brushOrigin(),5,5);
        painter.setBrushOrigin(100,100);
        painter.drawEllipse(painter.brushOrigin(),5,5);

    5、void setClipRect(const QRectF &rectangle, Qt::ClipOperation operation = Qt::ReplaceClip)

    启用剪辑,并使用给定的剪辑操作将剪辑区域设置为给定的矩形。

    裁剪操作Qt::ClipOperation

    • Qt::NoClip:关闭裁剪。
    • Qt::ReplaceClip:将当前的裁剪路径/矩形/区域替换为函数调用中提供的路径/矩形/区域
    • Qt::IntersectClip:与当前裁剪路径/矩形/区域与函数调用中提供的路径相交。
    void Widget::paintEvent(QPaintEvent *event)
    {
        auto rect = event->rect();
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing,true);
        painter.setPen(QPen(Qt::red,5));
        painter.setClipRect(rect.adjusted(20,20,-20,-20));
        painter.drawLine(rect.topLeft(),rect.bottomRight());
    }

    6、void setClipPath(const QPainterPath &path, Qt::ClipOperation operation = Qt::ReplaceClip)

    设置裁剪路径。

    void Widget::paintEvent(QPaintEvent *event)
    {
        auto rect = event->rect();
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing,true);
        painter.setBrush(Qt::cyan);
        QPainterPath path;
        path.addRoundRect(rect.adjusted(20,20,-20,-20),60,60);
        painter.setClipPath(path);
        painter.drawRect(rect);
    }

    7、void setClipRegion(const QRegion &region, Qt::ClipOperation operation = Qt::ReplaceClip)

    设置裁剪区域,见QRegion详解

    8、void drawArc(const QRect &rect, int startAngle, int lenAngle)

    绘制圆弧。

        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing,true);
        painter.setPen(QPen(Qt::red,5));
        QRectF rectangle(10.0, 20.0, 80.0, 60.0);
        int startAngle = 30 * 16;
        int spanAngle = 120 * 16;
        painter.drawArc(rectangle, startAngle, spanAngle);
        painter.setPen(QPen(Qt::blue,3,Qt::DotLine));
        painter.drawRect(rectangle);

    9、void drawChord(const QRectF &rectangle, int startAngle, int spanAngle)

    绘制扇形,参数含义和绘制弧形一样。

        painter.drawChord(rectangle, startAngle, spanAngle);

    10、void drawConvexPolygon(const QPointF *points, int pointCount)

    绘制凸多边形(凸多边形的内角均小于或等于180°)。第一个点隐式连接到最后一个点,并且多边形被当前的brush()填充。

        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing,true);
        painter.setPen(QPen(Qt::red,3));
    
        static const QPointF points[4] = { QPointF(10.0, 80.0),
                                           QPointF(20.0, 10.0),
                                           QPointF(80.0, 30.0),
                                           QPointF(90.0, 70.0)};
        painter.drawConvexPolygon(points, 4);

    11、void drawConvexPolygon(const QPolygonF &polygon)

    绘制凸多边形,重载函数。

        QPolygonF polygon;
        polygon.append(QPointF(10.0, 80.0));
        polygon.append(QPointF(20.0, 10.0));
        polygon.append(QPointF(80.0, 60.0));
        painter.drawConvexPolygon(polygon);

    12、void drawEllipse(const QRectF &rectangle)

    绘制椭圆,参数是椭圆的外切矩形。

    13、void drawEllipse(const QPointF &center, qreal rx, qreal ry)

    绘制椭圆,参数为椭圆的中心和x、y方向的半径。

    14、void drawImage(const QRectF &target, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags = Qt::AutoColor)

    将给定图像的矩形部分(参数3)源绘制到绘制设备中的目标矩形(参数1)中。如果图像和矩形尺寸不相同,则将图像缩放以适合矩形。

        QPainter painter(this);
        QImage img(":/D:/eee.jpg");
        QRectF r{40,40,100,200};
        painter.drawImage(r,img);

        QPainter painter(this);
        QImage img(":/D:/eee.jpg");
        QRectF r{40,40,100,200};
        painter.drawImage(r,img,QRectF(30,30,200,400));

    15、void drawLine(const QLineF &line)

    绘制直线。QLineF

    16、void drawPath(const QPainterPath &path)

    使用当前的笔绘制轮廓并使用当前的笔刷绘制路径。QPainterPath

    17、void drawPie(const QRectF &rectangle, int startAngle, int spanAngle)

    绘制扇形。扇形被当前的brush()填充。必须以度的1/16来指定startAngle和spanAngle,即一个完整的圆等于5760(16 * 360)。角度的正值表示逆时针方向,而负值表示顺时针方向。参考上面的drawArc()示意图。

        QPainter painter(this);
        QRectF rectangle(10.0, 20.0, 80.0, 60.0);
        int startAngle = 30 * 16;
        int spanAngle = 120 * 16;
    
        painter.setPen(QPen(Qt::red,5));
        painter.drawPie(rectangle, startAngle, spanAngle);
        painter.setPen(QPen(Qt::blue,3,Qt::DotLine));
        painter.drawRect(rectangle);

    18、void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)

    将给定像素图的矩形部分源绘制到绘画设备中的给定目标中。如果像素图和矩形大小不相同,则将像素图缩放为适合矩形。

        QPainter painter(this);
        QPixmap img(":/D:/eee.jpg");
        QRectF r{40,40,100,200};
        painter.drawPixmap(r,img,QRectF(30,30,200,400));

    19、void drawPixmap(const QPointF &point, const QPixmap &pixmap, const QRectF &source)

    在参数1的点处开始绘制参数3指定的图片区域,不会缩放

        QPainter painter(this);
        QPixmap img(":/D:/eee.jpg");
        painter.drawPixmap(QPointF(40,40),img,QRectF(30,30,200,400));

    20、void drawPixmap(const QPointF &point, const QPixmap &pixmap)

    在给定点开始绘制图片,不会缩放

    21、void drawPixmap(const QRect &rectangle, const QPixmap &pixmap)

    在矩形区域绘制图片,会缩放

    22、void drawPoint(const QPointF &position)

    绘制点。

        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setPen(QPen(Qt::red,5));
        painter.drawPoint(QPointF(40,40));
        painter.setPen(QPen(Qt::red,15));
        painter.drawPoint(QPointF(60,60));

    22、void drawPoints(const QPointF *points, int pointCount)

    绘制数组中的点。

        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setPen(QPen(Qt::red,5));
    
        static const QPointF points[4] = {
            QPointF(10.0, 80.0),
            QPointF(20.0, 10.0),
            QPointF(80.0, 30.0),
            QPointF(90.0, 70.0)
        };
        painter.drawPoints(points, 4);

    23、void drawPoints(const QPolygonF &points)

    绘制多边形中的点。

    24、void drawPolygon(const QPolygonF &points, Qt::FillRule fillRule = Qt::OddEvenFill)

    绘制多边形。QPolygon

    25、void drawPolyline(const QPointF *points, int pointCount)

    绘制折线。

        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setPen(QPen(Qt::red,5));
    
        static const QPointF points[3] = {
            QPointF(10.0, 80.0),
            QPointF(20.0, 10.0),
            QPointF(80.0, 30.0),
        };
        painter.drawPolyline(points, 3);

    26、void drawPolyline(const QPolygonF &points)

    绘制折线。

        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setPen(QPen(Qt::red,5));
        QPolygon polygon = QPolygon();
        polygon << QPoint(22,33)<<QPoint(78,45)<<QPoint(111,233)<<QPoint(234,88)<<QPoint(34,89);
        painter.drawPolyline(polygon);

    27、void drawRect(const QRectF &rectangle)

    绘制矩形。QRectF

    28、void drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode = Qt::AbsoluteSize)

    绘制圆角矩形。见QPainterPath

    29、void drawText(const QPointF &position, const QString &text)

    从给定位置开始,以当前定义的文本方向绘制给定文本。此函数不处理换行符(\ n),因为它不能将文本分成多行,也不能显示换行符。默认情况下,QPainter绘制抗锯齿的文本

    30、void drawText(const QRectF &rectangle, int flags, const QString &text, QRectF *boundingRect = nullptr)

    在提供的矩形内绘制给定的文本。矩形以及对齐标记定义了文本的锚点。

        auto rect = event->rect();
        QPainter painter(this);
        painter.setPen(QPen(Qt::red,5));
        painter.drawText(rect, Qt::AlignCenter, "黄河之水天上来\n奔流到海不复回");

    参数4是绘制的文本的外接矩形,例:

        auto rect = event->rect();
        QPainter painter(this);
        painter.setPen(QPen(Qt::red,5));
        QRectF boundingRect;
        painter.drawText(rect, Qt::AlignCenter, "黄河之水天上来\n奔流到海不复回", &boundingRect);
        painter.setPen(QPen(Qt::cyan,3,Qt::DotLine));
        painter.drawRect(boundingRect);

    参数2文本标识单独使用时的效果:

    • Qt::AlignLeft:文本靠左。
    • Qt::AlignRight:文本靠右。
    void Widget::paintEvent(QPaintEvent *event)
    {
        auto rect = event->rect();
        QPainter painter(this);
        painter.setPen(QPen(Qt::red,5));
        QFont font;
        font.setPixelSize(40);
        painter.setFont(font);
        painter.drawText(rect,Qt::AlignRight, "黄河之水天上来\n奔流到海不复回哈哈哈");
    }

    • Qt::AlignHCenter:水平方向居中。

    • Qt::AlignJustify:两端对齐,无效,原因未知。
    • Qt::AlignTop:文本靠上。
    • Qt::AlignBottom:文本靠下。
    • Qt::AlignVCenter:垂直方向居中。

    • Qt::AlignCenter:水平和垂直方向居中。
    • Qt::TextSingleLine:保持文本单行,把换行符当做空格。
        painter.drawText(rect,Qt::TextSingleLine, "黄河之水天上来\n奔流到海不复回哈哈哈");

    •  Qt::TextExpandTabs:这个资料语焉不详,我推测作用是复制一个制表符。
    void Widget::paintEvent(QPaintEvent *event)
    {
        auto rect = event->rect();
        QPainter painter(this);
        painter.setPen(QPen(Qt::red,5));
        QFont font;
        font.setPixelSize(40);
        painter.setFont(font);
        QString text = "A\tA";
        painter.drawText(rect,Qt::TextExpandTabs, text);
        painter.drawText(QPointF(0,80),text);
    
        auto bRect = painter.boundingRect(rect,Qt::TextExpandTabs,text);
        painter.drawRect(bRect);
    }

    使用这个标识之后多出了一个制表符空间。

    • Qt::TextShowMnemonic:将字符串“&P”显示为P。对于&号,请使用“&&”。例:
        QString text = "&ABC";
        painter.drawText(rect,Qt::TextShowMnemonic, text);
        painter.drawText(QPointF(0,80),text);

     

    • Qt::TextWordWrap:文字自动换行。

    31、void drawText(const QRectF &rectangle, const QString &text, const QTextOption &option = QTextOption())。

        QTextOption option(Qt::AlignLeft | Qt::AlignVCenter);
        option.setTextDirection(Qt::RightToLeft);
        painter.drawText(rect,"黄河之水天上来",option);

    32、void drawTiledPixmap(const QRectF &rectangle, const QPixmap &pixmap, const QPointF &position = QPointF())

    绘制平铺图片。绘制从图片中参数3的位置开始绘制。

        QPixmap pixmap(":/D:/666666.PNG");
        painter.drawTiledPixmap(rect,pixmap,QPointF(100,100));

    33、void eraseRect(const QRectF &rectangle)

    擦除区域。

    相当于:

        fillRect(rectangle, background());

    34、bool end()

    结束绘画。 释放绘画时使用的所有资源。

    35、void fillPath(const QPainterPath &path, const QBrush &brush)

    填充路径,但不绘制轮廓。

        QPainterPath path;
        path.cubicTo(QPointF(0,0),QPointF(200,200),QPointF(150,20));
        painter.fillPath(path,Qt::cyan);

    36、void fillRect(const QRect &rectangle, const QBrush &brush)

    填充矩形,可用颜色、画刷、渐变、画刷类型填充。

    37、bool isActive()

    是否已调用begin()而尚未调用end()。

    38、void resetTransform()

    重置使用translate(),scale(),shear(),rotate(),setWorldTransform(),setViewport()和setWindow()进行的所有转换。

    39、void restore()

    恢复当前的QPainter状态(从堆栈弹出保存的状态)。

    40、void save()

    保存当前的画家状态(将状态推送到堆栈上)。 在save()之后必须有一个相应的restore()。(end()函数会展开堆栈)

    41、void rotate(qreal angle)

    顺时针旋转坐标系。

        QPainter painter(this);
        painter.setPen(QPen(Qt::red,5));
        painter.translate(150,150);
        painter.drawText(QPointF(0,0),"黄河之水天上来");
        painter.rotate(90);
        painter.drawText(QPointF(0,0),"黄河之水天上来");
        painter.rotate(90);
        painter.drawText(QPointF(0,0),"黄河之水天上来");
        painter.rotate(90);
        painter.drawText(QPointF(0,0),"黄河之水天上来");

    42、void scale(qreal sx, qreal sy)

    坐标x、y轴缩放相应比例。

    43、void setBackground(const QBrush &brush)

    设置背景画刷。背景画刷是在绘制不透明文本、填充画刷样式和绘制位图时填充的画刷。背景笔刷在透明背景模式下没有效果(默认设置)。

    void Widget::paintEvent(QPaintEvent *event)
    {
        auto rect = event->rect();
        QPainter painter(this);
        painter.setBackgroundMode(Qt::OpaqueMode);
        painter.setBackground(Qt::cyan);
        painter.fillRect(rect,Qt::CrossPattern);
    }

        QPainter painter(this);
        painter.setBackgroundMode(Qt::OpaqueMode);
        painter.setBackground(Qt::cyan);
        painter.setPen(QPen(Qt::red,5));
        painter.drawText(QPointF(55,55),"黄河之水天上来");

    绘制位图:

        auto rect = event->rect();
        QPainter painter(this);
        painter.setBackgroundMode(Qt::OpaqueMode);
        painter.setBackground(Qt::cyan);
        QBitmap img(":/D:/qqq.jpeg");
        painter.drawPixmap(rect,img);

    44、void setBackgroundMode(Qt::BGMode mode)。

    设置背景模式。

    Qt::BGMode:

    • Qt::TransparentMode:(默认设置)绘制不透明文本、填充画刷样式和绘制位图时无需设置背景像素。
    • Qt::OpaqueMode:用当前背景色填充不透明文本、画刷样式和位图的背景像素。

    45、void setOpacity(qreal opacity)

    设置透明度。值为0.0~1.0。

    46、void setWorldTransform(const QTransform &transform, bool combine = false)

    设置变换矩阵。见QTransform。如果参数2是true,将与当前矩阵的变换效果合并,否则替换当前变换矩阵。

        QPainter painter(this);
        auto rectPoint = event->rect().center();
    
        QTransform transform;
        transform.translate(rectPoint.x(),rectPoint.y());
        painter.setWorldTransform(transform);
    
        QTransform transform2;
        transform2.rotate(45);
        painter.setWorldTransform(transform2,true);
    
        painter.setPen(QPen(Qt::cyan, 3, Qt::DashDotLine));
        painter.drawRect(0, 0, 100, 100);

    设置了两个变换矩阵,一个效果是平移,一个效果是旋转,第一次设置平移效果,第二次设置旋转和平移效果合并,即有平移和旋转两种效果。

    注:setTransform() 和 setWorldTransform()这俩没区别,查看源码发现setTransform实际上就是调用setWorldTransform:

    47、void setWindow(const QRect &rectangle)

    设置窗口转换矩形。见窗口-视口转换

    48、void setViewTransformEnabled(bool enable)

    设置是否启用窗口-视口转换。设置为false则相当于setWindow()的设置无效。

    49、void setViewport(const QRect &rectangle)

    设置视口。见窗口-视口转换

    50、void setWorldMatrixEnabled(bool enable)

    设置是否启用变换矩阵,设为false则相当于setTransform()的设置无效。

    51、void shear(qreal sh, qreal sv)

    剪切坐标,见QTransform

    52、void strokePath(const QPainterPath &path, const QPen &pen)

    使用指定的画笔描绘路径轮廓,其内部实际上是调用drawPath()。

     53、void translate(qreal dx, qreal dy)

    平移绘制坐标。

        QPainter painter(this);
        painter.translate(50,50);
        painter.drawText(QPointF(0,0),"黄河之水天上来");

    展开全文
  • QPainter显示视频流

    2018-07-10 09:13:35
    QPainter显示视频流,没有使用QLabel,其中有封装好的视频读取类。
  • 2.保证无毒 3.简单,方便,实用 4.实例可以自行改用 5.如有非法,本人无法律责任,由改动代码人负责! 6.更多本人作品,查找标签“朱建强” 7.请下载,杀毒后再使用!
  • 2.保证无毒 3.简单,方便,实用 4.实例可以自行改用 5.如有非法,本人无法律责任,由改动代码人负责! 6.更多本人作品,查找标签“朱建强” 7.请下载,杀毒后再使用!
  • PyQt5中QPainter类QBrush画刷使用大全实例源码:使用画刷QBrush绘制30张效果图
  • //for starf study #include "mainwindow.h" #include "ui_mainwindow.h" #include<QDebug>...QPainter> #include<QBrush> #include<QRectF > #include<QLineF> #include<.
  • QPainter类的CompositionMode各值含义

    千次阅读 2022-03-07 08:03:28
    QPainter::CompositionMode用法讲解
  • qt video,从基础开始,第13部分,一共14部分,使用vs2015的addin作为教学工具,很不错的。
  • QPainter可以绘制几何形状(点、线、矩形、椭圆、弧形、弦形、饼状图、多边形和贝塞尔曲线)

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,579
精华内容 8,231
关键字:

QPainter