界面优化 - 绘图

目录

1. 基本概念

2. 绘制各种形状

2.1 绘制线段

2.2 绘制矩形 

2.3 绘制圆形

2.4 绘制文本

2.5 设置画笔

2.6 设置画刷

3. 绘制图片

3.1 绘制简单图片

3.2 平移图片

3.3 缩放图片

3.4 旋转图片


1. 基本概念

虽然 Qt 已经内置了很多的控件, 但是不能保证现有控件就可以应对所有场景.

很多时候我们需要更强的 "自定制" 能力.

Qt 提供了画图相关的 API, 可以允许我们在窗上绘制任意的图形形状, 来完成更复杂的界面设计.

  • 所谓的 "控件" , 本质上也是通过画图的方式画上去的.

  • 画图 API 和 控件 之间的关系, 可以类比成机器指令和高级语言之间的关系.
  • 控件是对画图 API 的进一步封装; 画图 API 是控件的底层实现.

绘图 API 核心类:

说明
QPainter"绘画者" 或者 "画家". 用来绘图的对象, 提供了⼀系列 drawXXX 方法, 可以允许我们绘制各种图形.
QPaintDevice"画板". 描述了 QPainter 把图形画到哪个对象上. 像我们之前用过的 QWidget 也是⼀种 QPaintDevice (QWidget 是 QPaintDevice 的子类) .
QPen"画笔". 描述了 QPainter 画出来的线是什么样的.
QBrush"画刷". 描述了 QPainter 填充一个区域是什么样的.

绘图 API 的使用, 一般不会在 QWidget 的构造函数中使用, 而是要放到 paintEvent 事件中.

🌴关于 paintEvent

paintEvent 会在以下情况下被触发:

  • 控件首次创建.
  • 控件被遮挡, 再解除遮挡.
  • 窗口最小化, 再恢复
  • 控件大小发生变化时.
  • 主动调用 repaint() 或者 update() 方法. (这两个方法都是 QWidget 的方法).
  • ......

因此, 如果把绘图 api 放到构造函数中调用, 那么一旦出现上述的情况, 界面的绘制效果就无法确保符合预期了.

2. 绘制各种形状

2.1 绘制线段

void drawLine(const QPoint &p1, const QPoint &p2);

参数:

  • p1:绘制起点坐标
  • p2:绘制终点坐标

void drawLine ( int x1, int y1, int x2, int y2 );
参数:
  • x1,y1:绘制起点坐标
  • x2,y2:绘制终点坐标

示例:

1、在 "widget.h" 头文件中声明绘图事件;

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    
    // 声明绘图事件
    void paintEvent(QPaintEvent *event);

private:
    Ui::Widget *ui;
};

2、在 "widget.cpp" 文件中重写 paintEvent() 方法;

void Widget::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备
    QPainter painter(this);

    // 1. 画一条线
//    painter.drawLine(50, 50, 500, 50);

    // 2. 再画一条线
    painter.drawLine(QPoint(50, 50), QPoint(500, 50));
}

实现效果如下:

2.2 绘制矩形 

void QPainter::drawRect(int x, int y, int width, int height);

参数:

  • x:窗口横坐标;
  • y:窗口纵坐标;
  • width:所绘制矩形的宽度;
  • height:所绘制矩形的高度;

 示例:

void Widget::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备
    QPainter painter(this);

    // 绘制矩形
    painter.drawRect(100, 100, 300, 150);
}

实现效果如下:

 

2.3 绘制圆形

 void QPainter::drawEllipse(const QPoint &center, int rx, int ry)

参数:

  • center:中心点坐标
  • rx:横坐标
  • ry:纵坐标

  示例:

void Widget::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备
    QPainter painter(this);

    // 绘制圆
    painter.drawEllipse(QPoint(300, 300), 100, 100);
}

 实现效果如下:

2.4 绘制文本

        QPainter类 中不仅提供了绘制图形的功能,还可以使用 QPainter::drawText() 函数来绘制文字也可以使用 QPainter::setFont() 设置字体等信息。

示例:

void Widget::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备
    QPainter painter(this);

    // 设置字体
    QFont font("华文行楷", 25);
    painter.setFont(font);

    // 设置画笔颜色
    painter.setPen(Qt::blue);

    // 画文字
    painter.drawText(300, 250, "草长莺飞");
}

 实现效果如下:

2.5 设置画笔

        QPainter 在绘制时,是有一个默认的画笔的。在使用时也可以自定义画笔。在 Qt 中,QPen类中定义了 QPainter 应该如何绘制形状、线条和轮廓。同时通过 QPen类 可以设置画笔的线宽、颜色、样式、画刷等。

        画笔的颜色可以在实例化画笔对象时进行设置,画笔的宽度是通过 setWidth() 方法进行设置,画笔的风格是通过setStyle()方法进行设置,画笔的颜色主要是通过 QColor 类设置,设置画刷主要是通过 setBrush() 方法。

  • 设置画笔颜色:QPen::QPen(const QColor &color)
  • 设置画笔宽度:void QPen::setWidth(int width)
  • 设置画笔风格:void QPen::setStyle(Qt::PenStyle style)

画笔的风格有:


示例:画笔的使用

void Widget::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备
    QPainter painter(this);

    // 设置画笔
    QPen pen(QColor(0, 255, 255));

    // 设置画笔宽度
    pen.setWidth(5);

    // 设置画笔风格
    pen.setStyle(Qt::DashLine);

    // 让画家使用画笔
    painter.setPen(pen);

    // 绘制圆
    painter.drawEllipse(QPoint(300, 300), 100, 100);
}

实现效果如下:

2.6 设置画刷

        在 Qt 中,画刷是使用 QBrush类 来描述,画刷大多用于填充。QBrush定义了QPainter的填充模式,具有样式、颜色、渐变以及纹理等属性。

        画刷的格式中定义了填充的样式,使用 Qt::BrushStyle 枚举,默认值是 Qt::NoBrush,也就是不进行任何填充。可以通过 Qt 助手查找画刷的格式。如下图示:

设置画刷主要通过 void QPen::setBrush(const QBrush &brush) 方法,其参数为画刷的格式


示例:

void Widget::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备
    QPainter painter(this);

    // 设置画刷,给封闭图形填充颜色
    QBrush brush(QColor(255, 0, 255));

    // 设置画刷风格
    brush.setStyle(Qt::DiagCrossPattern);

    // 让画家使用画刷
    painter.setBrush(brush);

    // 绘制圆
    painter.drawEllipse(QPoint(300, 300), 100, 100);
}

 实现效果如下:

3. 绘制图片

        Qt 提供了四个类来处理图像数据:QImage、QPixmap、QBitmap 和 QPicture,它们都是常用的绘图设备。其中QImage主要用来进行 I/O 处理,它对 I/O 处理操作进行了优化,而且可以用来直接访问和操作像素;QPixmap 主要用来在屏幕上显示图像,它对在屏幕上显示图像进行了优化;QBitmap 是 QPixmap 的子类,用来处理颜色深度为1的图像,即只能显示黑白两种颜色;QPicture 用来记录并重演 QPainter 命令。

3.1 绘制简单图片

1. 新建 Qt 项目,基类选择 QWidget,项目名称为 QPainter。在 "widget.h" 头文件中声明绘画事件;如下图示:

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    
    // 声明绘画事件
    void paintEvent(QPaintEvent *event);

private:
    Ui::Widget *ui;
};

2. 创建 resource.qrc,并导入图片

3. 在 "widget.cpp" 文件中实现画图片功能;

void Widget::paintEvent(QPaintEvent *event)
{
    // 实例化画家对象
    (void)event;
    QPainter painter(this);

    // 画图片
    painter.drawPixmap(0, 0, QPixmap(":/fengche.jpg"));
}

实现效果如下:

3.2 平移图片

        平移图片实际是通过改变坐标来实现。QPainter类中提供了 translate()函数 来实现坐标原点的改变。

示例:

void Widget::paintEvent(QPaintEvent *event)
{
    // 实例化画家对象
    (void)event;
    QPainter painter(this);

    // 平移图片
    painter.translate(100, 100);

    // 画图片
    painter.drawPixmap(0, 0, QPixmap(":/fengche.jpg"));
}

实现效果如下:

3.3 缩放图片

在 Qt 中,图片的放大和缩小可以使用 QPainter类 中的 drawPixmap()函数 来实现。

示例:

void Widget::paintEvent(QPaintEvent *event)
{
    // 实例化画家对象
    (void)event;
    QPainter painter(this);

    QPixmap pixmap(":/fengche.jpg");

    // 缩放图片
    // 以(100,100)点开始画图,图片尺寸变为:400 * 300
    painter.drawPixmap(100, 100, 400, 300, pixmap);
}

实现效果如下:

3.4 旋转图片

图片的旋转使用的是 QPainter类 中的 rotate()函数,它默认是以原点为中心进行旋转的。如果要改变旋转的中心,可以使用 translate()函数 完成。

示例:

void Widget::paintEvent(QPaintEvent *event)
{
    // 实例化画家对象
    (void)event;
    QPainter painter(this);

    QPixmap pixmap(":/fengche.jpg");

    // 顺时针旋转 180 度
    painter.rotate(180);

    painter.translate(-800, -600);
    painter.drawPixmap(100, 100, 400, 300, pixmap);
}

实现效果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南风与鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值