Windows图形界面(GUI)-QT-C/C++ - Qt图形绘制详解

目录

Qt绘图基础

QPainter概述

基本工作流程

绘图事件系统

paintEvent事件

重绘机制

文字绘制技术

基本文字绘制

​编辑

高级文字效果

基本图形绘制

线条绘制

​编辑

形状绘制

​编辑

图片处理

基本图片绘制

高级图片效果

​编辑

特效与动画

渐变效果

​编辑

时钟绘制


Qt绘图基础

QPainter概述

QPainter是Qt中的核心绘图类,提供了高度抽象的2D绘图功能。它允许我们在各种设备上进行绘制,包括:

  • 窗口部件(QWidget)
  • 像素图(QPixmap)
  • 图像(QImage)

基本工作流程

cpp 复制代码
void Widget::paintEvent(QPaintEvent* event)
{
    QPainter painter(this);  

    // 设置绘图属性
    painter.setRenderHint(QPainter::Antialiasing); 

    // 进行绘制操作
    painter.drawLine(0, 0, 100, 100);
}

绘图事件系统

paintEvent事件

paintEvent是Qt中处理绘制的核心事件,在以下情况会被触发:

  • 窗口首次显示
  • 窗口从最小化恢复
  • 窗口被其他窗口遮挡后重新显示
  • 调用update()或repaint()函数

重绘机制

cpp 复制代码
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void paintEvent(QPaintEvent* event) override
    {
        QPainter painter(this);
        // 绘制代码
    }

    void updateContent()
    {
        update();  // 请求重绘,异步
        // repaint();  // 立即重绘,同步
    }

private:
    Ui::Widget *ui;
};

文字绘制技术

基本文字绘制

cpp 复制代码
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void paintEvent(QPaintEvent*) override
    {
        QPainter painter(this);

        // 设置字体
        QFont font("Arial", 20);
        font.setBold(true);
        painter.setFont(font);

        // 设置颜色
        painter.setPen(QColor(255, 0, 0));

        // 绘制文本
        painter.drawText(rect(), Qt::AlignCenter, "Hello Qt!");
    }

private:
    Ui::Widget *ui;
};

高级文字效果

cpp 复制代码
    void paintEvent(QPaintEvent*) override
    {
        QPainter painter(this);

        // 文字阴影效果
        QFont font("Times", 40);
        painter.setFont(font);

        // 绘制阴影
        painter.setPen(QColor(0, 0, 0, 127));
        painter.drawText(rect().adjusted(2, 2, 2, 2),
                         Qt::AlignCenter, "Shadow Text");

        // 绘制主文本
        painter.setPen(Qt::white);
        painter.drawText(rect(), Qt::AlignCenter, "Shadow Text");
    }

基本图形绘制

线条绘制

cpp 复制代码
void paintEvent(QPaintEvent*) override  
{  
    QPainter painter(this);  
    
    // 设置画笔  
    QPen pen(Qt::red, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);  
    painter.setPen(pen);  
    
    // 绘制各种线条  
    painter.drawLine(10, 10, 100, 100);  // 直线  
    painter.drawArc(10, 120, 80, 80, 0, 180 * 16);  // 圆弧  
}

形状绘制

cpp 复制代码
   void paintEvent(QPaintEvent*) override  
    {  
        QPainter painter(this);  
        
        // 矩形  
        painter.fillRect(10, 10, 90, 60, Qt::blue);  
        
        // 圆形  
        painter.drawEllipse(120, 10, 90, 90);  
        
        // 多边形  
        QPolygon polygon;  
        polygon << QPoint(10,100) << QPoint(110,100)   
                << QPoint(60,180);  
        painter.drawPolygon(polygon);  
    }

图片处理

基本图片绘制

cpp 复制代码
void paintEvent(QPaintEvent*) override  
{  
    QPainter painter(this);  
    
    QPixmap pixmap(":/images/example.png");  
    painter.drawPixmap(10, 10, pixmap);  
}

高级图片效果

cpp 复制代码
    void paintEvent(QPaintEvent*) override
    {
        QPainter painter(this);

        QPixmap pixmap("C:\\Users\\Administrator\\Desktop\\图形界面-QT.png");

        // 图片缩放
        QPixmap scaled = pixmap.scaled(200, 200,
                                       Qt::KeepAspectRatio,
                                       Qt::SmoothTransformation);

        // 添加圆形裁剪
        QPainterPath path;
        path.addEllipse(10, 10, 200, 200);
        painter.setClipPath(path);
        painter.drawPixmap(10, 10, scaled);
    }

特效与动画

渐变效果

cpp 复制代码
void paintEvent(QPaintEvent*) override  
{  
    QPainter painter(this);  
    
    // 线性渐变  
    QLinearGradient gradient(0, 0, width(), height());  
    gradient.setColorAt(0, Qt::red);  
    gradient.setColorAt(1, Qt::blue);  
    
    painter.fillRect(rect(), gradient);  
}

时钟绘制

cpp 复制代码
class ClockWidget : public QWidget
{
    Q_OBJECT

public:
    explicit ClockWidget(QWidget *parent = nullptr) : QWidget(parent)
    {

        setFixedSize(400, 400);

        QTimer *timer = new QTimer(this);
        connect(timer, &QTimer::timeout, this, QOverload<>::of(&ClockWidget::update));
        timer->start(1000);
    }

protected:
    void paintEvent(QPaintEvent *event) override
    {
        Q_UNUSED(event);

        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);

        painter.translate(width() / 2, height() / 2);

        QTime currentTime = QTime::currentTime();

        drawClockPlate(&painter);

        drawHourHand(&painter, currentTime);

        drawMinuteHand(&painter, currentTime);

        drawSecondHand(&painter, currentTime);

        drawCenterPoint(&painter);
    }

private:
    void drawClockPlate(QPainter *painter)
    {

        QPen pen(Qt::black);
        pen.setWidth(2);
        painter->setPen(pen);

        painter->setBrush(Qt::white);

        painter->drawEllipse(-180, -180, 360, 360);

        for (int i = 0; i < 60; ++i) {

            painter->save();

            painter->rotate(6.0 * i);

            if (i % 5 == 0) {

                pen.setWidth(3);
                painter->setPen(pen);
                painter->drawLine(0, -160, 0, -145);

                painter->save();
                painter->rotate(-6.0 * i);
                QFont font("Arial", 15, QFont::Bold);
                painter->setFont(font);

                int num = (i / 5 == 0) ? 12 : i / 5;

                QRect textRect(-20, -190, 40, 40);
                painter->drawText(textRect, Qt::AlignCenter, QString::number(num));
                painter->restore();
            } else {

                pen.setWidth(1);
                painter->setPen(pen);
                painter->drawLine(0, -160, 0, -150);
            }

            painter->restore();
        }
    }

    void drawHourHand(QPainter *painter, const QTime &time)
    {
        painter->save();

        double angle = 30.0 * (time.hour() % 12) + 0.5 * time.minute();
        painter->rotate(angle);

        QPen pen(Qt::black, 4);
        painter->setPen(pen);

        painter->drawLine(0, 0, 0, -80);

        painter->restore();
    }

    void drawMinuteHand(QPainter *painter, const QTime &time)
    {
        painter->save();

        double angle = 6.0 * time.minute() + 0.1 * time.second();
        painter->rotate(angle);

        QPen pen(Qt::blue, 3);
        painter->setPen(pen);

        painter->drawLine(0, 0, 0, -120);

        painter->restore();
    }

    void drawSecondHand(QPainter *painter, const QTime &time)
    {
        painter->save();

        double angle = 6.0 * time.second();
        painter->rotate(angle);

        QPen pen(Qt::red, 2);
        painter->setPen(pen);

        painter->drawLine(0, 20, 0, -140);

        painter->restore();
    }

    void drawCenterPoint(QPainter *painter)
    {
        painter->setPen(Qt::NoPen);
        painter->setBrush(Qt::red);
        painter->drawEllipse(-8, -8, 16, 16);

        painter->setBrush(Qt::black);
        painter->drawEllipse(-4, -4, 8, 8);
    }
};
相关推荐
奥特曼狂扁小怪兽5 分钟前
C++ QT 自绘表盘
开发语言·c++·qt
Sakuya__6 分钟前
Qt QComboBox的QSS美化
qt·qss·qcombobox
努力学习java的哈吉米大王20 分钟前
初识JAVA-面向对象的三大特征之多态
java·开发语言
汤姆和杰瑞在瑞士吃糯米粑粑23 分钟前
【C++学习篇】红黑树 从入门到进阶
数据结构·c++·算法
冰茶_28 分钟前
C#异步和多线程,Thread,Task和async/await关键字--12
开发语言·学习·c#·visual studio
前端熊猫1 小时前
二进制、八进制、十进制和十六进制的相互转换
c语言·开发语言·二进制·十六进制·八进制
S-X-S1 小时前
自定义异常模块
java·开发语言·spring boot
重生之Java开发工程师1 小时前
Java中Map常用遍历方式以及性能对比
java·开发语言
Xiezequan1 小时前
c++ 手写queue循环队列
开发语言·c++
计算机小混子1 小时前
C++实现设计模式--- 观察者模式 (Observer)
c++·观察者模式·设计模式