QT 学习笔记(十)

简介: QT 学习笔记(十)

文章目录




由于每次代码都是在原有程序上修改,因此除了新建项目,不然一般会在学完后统一展示代码。

提示:具体项目创建流程和注意事项见QT 学习笔记(一)

提示:具体项目准备工作和细节讲解见QT 学习笔记(二)


一、绘图

  • 生成一个新的项目,具体步骤过程见提示。

1. 理论知识储备


使用 QT 画图的操作比较类似对文件进行操作,不会太难,控件较多。

QT 的绘图系统允许使用相同的 API 在屏幕和其它打印设备上进行绘制。

整个绘图系统基于 QPainter,QPainterDevice 和 QPaintEngine 三个类。

QPainter 是用来执行绘制的操作;

QPaintDevice 是一个二维空间的抽象,这个二维空间允许QPainter在其上面进行绘制,也就是QPainter工作的空间;

QPaintEngine 提供了画笔(QPainter)在不同的设备上进行绘制的统一的接口。QPaintEngine 类应用于 QPainter 和 QPaintDevice 之间,通常对开发人员是透明的。除非需要自定义一个设备,否则是不需要关心 QPaintEngine 这个类的。

因此,我们可以把 QPainter 理解成画笔;把 QPaintDevice 理解成使用画笔的地方,比如纸张、屏幕等;而对于纸张、屏幕而言,肯定要使用不同的画笔绘制,为了统一使用一种画笔,我们设计了 QPaintEngine 类,这个类让不同的纸张、屏幕都能使用一种画笔。

下图给出了这三个类之间的层次结构:


9d7a82b95ea94e208c32a910fbfa8969.png


  • 由这个层次结构可知,QT 的绘图系统实际上是,使用 QPainter 在 QPainterDevice 上进行绘制,它们之间使用 QPaintEngine 进行通讯(也就是翻译 QPainter 的指令)。

2. 画背景图


在使用 QT 进行窗口绘图时,一定要选择 QWidget。

39bdb6a271f349458f671cd79b7954fe.png


在绘图事件当中,我们需要注意的是:

(1) 在主窗口头文件 widget.h 当中的 protected 下进行重写绘图事件的定义。

(2) 如果我们想要在窗口绘图,就必须放在绘图事件里实现。

(3) 当窗口需要重绘的时候,也就是窗口的状态发生改变,就像我们点击按钮,调整窗口的大小使其发生变化等操作,绘图事件会内部自动调用。

当我们进行绘图事件构造函数的编写时,通过调用帮助文档(如下图所示),得知需要指定一个绘图设备,指定当前设备使用 this 指针即可。

4464dfd933674013add19136cf1df2ae.png


对于绘图事件当中,绘图设备的指定有如下方法:

方法一:QPainter p(this);然后直接进行绘图操作。

方法二:首先,创建画家对象 QPainter p;然后指定当前窗口为绘图设备 p.begin(this);但是需要在结束时使用 p.end();在 begin 和 end 之间进行绘图操作,p.drawxxx()。

在上述工作完成后,开始进行背景图的绘制。背景图的绘制函数为:

   //画背景图

    //画背景图
    p.drawPixmap(0,0,width(),height(),QPixmap("../tuoian/5.jpg"));
    //p.drawPixmap(rect(),QPixmap("../tuoian/5.jpg"));


在我们一般背景图的绘制过程当中,通常是窗口有多大就绘制多大。因此,从 0,0 坐标开始,也就是窗口的左上角,然后选择窗口的宽度函数 width() 和窗口的高度函数 height(),最后定义图片的标签,这里需要注意的是,图片所在的路径要与代码所在的上一级路径相同,不要放到代码所在的文件夹当中,除非是资源,否则会看不到图片。路径放置如下图所示:


b6eade5aafa04f7cb1a1e00d61ce1dee.png


得到如下实现结果:

12e0b58ccae34b9a92c146f4375359c3.png


当我们用鼠标更改图片大小时,背景图不会发生变化。

4d671aa91dfe4a298973c8837f9b0126.png


3. 简单绘图


  • 记住要先画背景,在画其他的,否则会被背景覆盖。
  • 在绘图函数中不要进行太过于复杂的数据处理,否则程序运行很慢。
  • 画直线:这四个参数分别表示起点的 x 坐标和 y 坐标,终点的 x 坐标和 y 坐标。
    //画直线
    p.drawLine(50,50,150,50);
    p.drawLine(50,50,50,150);


f72a6d894fa3445a81b2dac82b335d8b.png


  • 在这里,我们发现画的直线有点窄,可能会导致在实际情况当中看不清。因此,我们要定义一个画笔。
  • 画笔:画笔的头文件是 QPen ,这里的宽度单位是像素。当设置好画笔的线宽之后,仍需将把画笔交给画家,这样我们设置的线宽才会发生作用。
    //定义画笔
    QPen pen;
    pen.setWidth(5);//设置线宽
    //把画笔交给画家
    p.setPen(pen);

7ab9937fc20242a599a4c5fc605b3c34.png


  • 除了对线宽进行设置外,还可以对线的颜色、样式等属性进行设置(具体现象不做演示,只讲方法)。
  • 颜色有两种设置方法:可以直接使用 red、blue 等简单颜色;也可以使用 RGB 对颜色进行设置(这里有一个小技巧,我们可以将鼠标放到设置的颜色上,就会显现出具体的颜色)。

f55a25ea1eae4fe7a9e12381216c8d01.png


  • 样式可以通过调用帮助文档,选择我们所需要的(其他的属性也是一样的道理,通过 f1 调用帮助文档查看即可)。

d14ce817de084dab92ad2f62a010c222.png


画图形:

p.drawRect() 是矩形绘画函数,其参数分别表示起点的 x 坐标,起点的 y 坐标,矩形的长度,矩形的宽度(起点坐标是相对于窗口的右上角而言的)。

p.drawEllipse() 是圆形绘画函数,其参数分别表示圆心所在点的坐标,水平上圆的半径,垂直上圆的半径(当水平半径和垂直半径相同时就是圆,不同就是椭圆)


    //画矩形
    p.drawRect(150,150,100,50);
    //画圆
    p.drawEllipse(QPoint(150,150),50,25);

e373ec4c344542fbb1d560d70d7f2718.png


  • 在这里我们发现,只有所画图形的轮廓,如果我们想要将其内部进行填充,就需要使用画刷工具。
  • 画刷:画刷的头文件是 QBrush 。画刷的颜色和样式设置方法与画笔相同,在此就不过多赘述了。将画刷的各项属性设置完成后,还需将画刷交给画家,这样子才可以正确使用。
    //创建画刷对象
    QBrush brush;
    brush.setColor(Qt::red);//设置简单颜色
    brush.setStyle(Qt::Dense1Pattern);//设置样式
    //把画刷交给画家
    p.setBrush(brush);

c9dafb9c05e8469c95cb84166c30ac7d.png


4. 手动刷新窗口


手动刷新窗口,需要我们对窗口进行重绘。其现象应该是当我们按下按钮,整个窗口进行重绘,图形按指定方式进行移动,因此,要先在 ui 界面上放置一个按钮,并将按钮转到槽函数,单击 on_pushButton_clicked() 函数即可。代码和实现现象如下所示:

void Widget::on_pushButton_clicked()
{
    x+=20;//每点击一下水平向右移动20
    if(x>width())
    {
        x=0;
    }
    //刷新窗口,让窗口重绘,整个窗口都刷新
    update();//间接调用paintEvent()
}


这里需要注意的是,update() 不要放在 paintEvent() 函数下,否则会造成死循环。

6f2acaf3b2b64d908af7f2d5a9016827.png

c392dbc97ac6496e83076fa24a81bea2.png


二、绘图实现代码

1. 主窗口头文件 widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();
protected:
    //重写绘图事件,虚函数
    //如果在窗口绘图,必须放在绘图事件里实现
    //绘图事件内部自动调用,窗口需要重绘的时候(窗口状态改变,例如:点击按钮,窗口大小变化)
    void paintEvent(QPaintEvent *);
private slots:
    void on_pushButton_clicked();
private:
    Ui::Widget *ui;
    int x;
};
#endif // WIDGET_H


2. 主窗口头文件 widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QPen>
#include <QBrush>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    x=0;//初始坐标设置为0
}
Widget::~Widget()
{
    delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
    // 方法一:
    //QPainter p(this);
    //方法二:
    QPainter p; //创建画家对象
    p.begin(this); //指定当前窗口为绘图设备
    //begin和end之间是绘图操作
    //p.drawxxx();
    //画背景图
    p.drawPixmap(0,0,width(),height(),QPixmap("../tuoian/5.jpg"));
    //p.drawPixmap(rect(),QPixmap("../tuoian/5.jpg"));
    //定义画笔
    QPen pen;
    pen.setWidth(5);//设置线宽
    //pen.setColor(Qt::red);//设置简单颜色
    pen.setColor(QColor(124,9,234));//RGB设置颜色
    pen.setStyle(Qt::DashLine);//设置线的风格
    //把画笔交给画家
    p.setPen(pen);
    //画直线
    p.drawLine(50,50,150,50);
    p.drawLine(50,50,50,150);
    //创建画刷对象
    QBrush brush;
    brush.setColor(Qt::red);//设置简单颜色
    brush.setStyle(Qt::Dense1Pattern);//设置样式
    //把画刷交给画家
    p.setBrush(brush);
    //画矩形
    p.drawRect(150,150,100,50);
    //画圆
    p.drawEllipse(QPoint(150,150),50,25);
    //画运动图形
    p.drawPixmap(x,180,80,80,QPixmap("‪../tuoian/6.jpg"));
    p.end();
}
void Widget::on_pushButton_clicked()
{
    x+=20;//每点击一下水平向右移动20
    if(x>width())
    {
        x=0;
    }
    //刷新窗口,让窗口重绘,整个窗口都刷新
    update();//间接调用paintEvent()
}




























相关文章
|
4天前
【Qt 学习笔记】按钮实现helloworld | 信号与槽概述
【Qt 学习笔记】按钮实现helloworld | 信号与槽概述
31 0
|
4天前
|
C++
Qt6学习笔记九(自定义控件封装)
Qt6学习笔记九(自定义控件封装)
79 0
|
4天前
|
安全 编译器 开发者
【Qt 学习笔记】Qt信号和槽的其他说明及Lambda表达式
【Qt 学习笔记】Qt信号和槽的其他说明及Lambda表达式
39 0
|
4天前
Qt6学习笔记三(QMainWindow、菜单栏、工具栏、状态栏、铆接部件、核心部件)
Qt6学习笔记三(QMainWindow、菜单栏、工具栏、状态栏、铆接部件、核心部件)
58 0
|
4天前
|
容器
Qt6学习笔记七(ToolButton、RadioButton、GroupBox、CheckBox、ListWidget、TreeWidget、TableWidget)
Qt6学习笔记七(ToolButton、RadioButton、GroupBox、CheckBox、ListWidget、TreeWidget、TableWidget)
51 0
|
4天前
Qt6学习笔记五(自定义对话框、QMessageBox、QColorDialog、QFileDialog、QFontDialog)
Qt6学习笔记五(自定义对话框、QMessageBox、QColorDialog、QFileDialog、QFontDialog)
48 0
|
4天前
|
开发框架 数据可视化 前端开发
【Qt 学习笔记】Qt控件概述
【Qt 学习笔记】Qt控件概述
29 0
|
4天前
|
编译器 C++ 索引
【Qt 学习笔记】详解Qt中的信号和槽
【Qt 学习笔记】详解Qt中的信号和槽
33 0
|
4天前
【Qt 学习笔记】输入框实现helloworld | QLineEdit的使用
【Qt 学习笔记】输入框实现helloworld | QLineEdit的使用
22 1
|
4天前
|
XML 自然语言处理 C++
【Qt 学习笔记】使用两种方式实现helloworld
【Qt 学习笔记】使用两种方式实现helloworld
23 1

推荐镜像

更多