QT 学习笔记(十)

2023-11-11

由于每次代码都是在原有程序上修改,因此除了新建项目,不然一般会在学完后统一展示代码。
提示:具体项目创建流程和注意事项见QT 学习笔记(一)
提示:具体项目准备工作和细节讲解见QT 学习笔记(二)

一、绘图

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

1. 理论知识储备

  • 使用 QT 画图的操作比较类似对文件进行操作,不会太难,控件较多。
  • QT 的绘图系统允许使用相同的 API 在屏幕和其它打印设备上进行绘制。
  • 整个绘图系统基于 QPainter,QPainterDevice 和 QPaintEngine 三个类。
  • QPainter 是用来执行绘制的操作;
  • QPaintDevice 是一个二维空间的抽象,这个二维空间允许QPainter在其上面进行绘制,也就是QPainter工作的空间;
  • QPaintEngine 提供了画笔(QPainter)在不同的设备上进行绘制的统一的接口。QPaintEngine 类应用于 QPainter 和 QPaintDevice 之间,通常对开发人员是透明的。除非需要自定义一个设备,否则是不需要关心 QPaintEngine 这个类的。
  • 因此,我们可以把 QPainter 理解成画笔;把 QPaintDevice 理解成使用画笔的地方,比如纸张、屏幕等;而对于纸张、屏幕而言,肯定要使用不同的画笔绘制,为了统一使用一种画笔,我们设计了 QPaintEngine 类,这个类让不同的纸张、屏幕都能使用一种画笔。
  • 下图给出了这三个类之间的层次结构:

在这里插入图片描述

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

2. 画背景图

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

在这里插入图片描述

  • 在绘图事件当中,我们需要注意的是:
  • (1) 在主窗口头文件 widget.h 当中的 protected 下进行重写绘图事件的定义。
  • (2) 如果我们想要在窗口绘图,就必须放在绘图事件里实现。
  • (3) 当窗口需要重绘的时候,也就是窗口的状态发生改变,就像我们点击按钮,调整窗口的大小使其发生变化等操作,绘图事件会内部自动调用。
  • 当我们进行绘图事件构造函数的编写时,通过调用帮助文档(如下图所示),得知需要指定一个绘图设备,指定当前设备使用 this 指针即可。

在这里插入图片描述

  • 对于绘图事件当中,绘图设备的指定有如下方法:
  • 方法一: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(),最后定义图片的标签,这里需要注意的是,图片所在的路径要与代码所在的上一级路径相同,不要放到代码所在的文件夹当中,除非是资源,否则会看不到图片。路径放置如下图所示:

在这里插入图片描述

  • 得到如下实现结果:

在这里插入图片描述

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

在这里插入图片描述

3. 简单绘图

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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

  • 画图形
  • p.drawRect() 是矩形绘画函数,其参数分别表示起点的 x 坐标,起点的 y 坐标,矩形的长度,矩形的宽度(起点坐标是相对于窗口的右上角而言的)。
  • p.drawEllipse() 是圆形绘画函数,其参数分别表示圆心所在点的坐标,水平上圆的半径,垂直上圆的半径(当水平半径和垂直半径相同时就是圆,不同就是椭圆)。
    //画矩形
    p.drawRect(150,150,100,50);
    
    //画圆
    p.drawEllipse(QPoint(150,150),50,25);

在这里插入图片描述

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

在这里插入图片描述

4. 手动刷新窗口

  • 手动刷新窗口,需要我们对窗口进行重绘。其现象应该是当我们按下按钮,整个窗口进行重绘,图形按指定方式进行移动,因此,要先在 ui 界面上放置一个按钮,并将按钮转到槽函数,单击 on_pushButton_clicked() 函数即可。代码和实现现象如下所示:
void Widget::on_pushButton_clicked()
{
    x+=20;//每点击一下水平向右移动20
    if(x>width())
    {
        x=0;
    }
    
    //刷新窗口,让窗口重绘,整个窗口都刷新
    update();//间接调用paintEvent()
}
  • 这里需要注意的是,update() 不要放在 paintEvent() 函数下,否则会造成死循环。

在这里插入图片描述
在这里插入图片描述

二、绘图实现代码

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()
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT 学习笔记(十) 的相关文章

  • 在 Qt5 中,是否需要 Q_INVOKABLE 来从 QML 调用公共 QObject 函数?

    我刚刚意识到我可以调用暴露于 QML 的对象的几乎任何函数 现在我对 Q INVOKABLE 很好奇 Qt5docs http doc qt io qt 5 qtqml cppintegration exposecppattributes
  • 如何将图像显示为缩略图

    我有一个QTreeView显示硬盘驱动器和目录 我也有一个QListView显示图像文件如下 但我想将图像显示为缩略图 如下所示 My code mainWidget mainWidget QWidget parent QWidget pa
  • QToolButton:更改菜单位置

    使用菜单时QToolButton菜单显示在按钮的正下方 有没有办法在按钮的左侧 右侧显示菜单 我知道这个问题不久前已得到回答 但我想为此问题添加新答案 因为接受的答案不再有效 实际上 更改 QToolButton 上的菜单位置非常容易 您需
  • 退出 Qt 程序的正确方法?

    我应该如何退出 Qt 程序 例如在加载数据文件时 发现文件损坏 并且用户需要退出该应用程序或重新启动数据文件 我是不是该 call exit EXIT FAILURE call QApplication quit call QCoreApp
  • Qt 布局,在小部件大小更改后调整到最小大小

    基本上我有一个QGridLayout里面有一些小部件 最重要的是 2 个标签 我用它们将图像绘制到屏幕上 好吧 如果用户愿意 他可以更改传入图像的分辨率 从而强制标签调整大小 我们假设标签的初始大小是320x240 用户将 VideoMod
  • Qt:测量事件处理时间

    我想测量我的应用程序中的哪些事件在主线程中需要很长时间才能执行 阻塞 GUI 或者至少是否有任何事件花费的时间超过 比如说 10 毫秒 显然 我对需要很长时间的任务使用线程和并发 但有时很难在其他线程中放入的内容和可以保留在 GUI 中的内
  • QT从QTableWidgetItem继承到Widget并覆盖'<'运算符

    我想要一个QTableWidget具有定制的某些单元QProgressBars 并且我希望能够对包含这些的列进行排序 我的定制QProgressBar继承自两者QProgressBar and QTableWidgetItem 并且我正在覆
  • 如何使用meta-toolchain-qt5构建Qt(带有QtWebEngine支持)?

    我正在尝试使用构建 Qtmeta toolchain qt5 但是当我通过这样做时poky glibc x86 64 meta toolchain qt5 cortexa7hf vfp vfpv4 neon toolchain 2 0 1
  • QSerialPort 中的 readAll() 不包括最后发送的响应

    我正在使用 Qt 来控制串行设备 如果我向串行设备发送命令 我会执行类似的操作serial gt write command r n 我制作了一个按钮 它将纯文本小部件内的文本更改为串行端口的响应 为了获得串口的响应 我使用serial g
  • 如何将 zlib 添加到现有的 qt 安装中

    如何将 zlib 添加到 Qt 的现有安装中 我对此很陌生 所以请给我详细的描述 提前感谢您的帮助 zlib 包含在 Qt 核心库中 如果你想在 Qt 程序中使用 zlib 函数 你只需要包含 src 3rdparty zlib 中的 zl
  • 如何向同一个 QMenu 添加多个 QAction?

    我正在尝试实现 Qt 菜单自定义 并且我提供了一个功能来添加相同的功能QAction在同一个人民币上下文菜单中多次 但是当我尝试这样做时 myMenu gt addAction myAction myMenu gt addAction my
  • Mac 上的 Qt — 如何访问帮助菜单中的“搜索”

    我正在将我的 Qt 应用程序移植到 Mac OS X 在 Windows Linux 上 我使用 QLineEdit 在帮助菜单中提供搜索功能 In Mac OS X I saw something like this is built i
  • 静态变量中的 qt tr()

    我在 qt 中的翻译方面遇到问题 我的项目中的所有翻译都工作正常 但有一个翻译位于类的静态变量中 相应部分代码如下 头文件类似于这样 typedef struct int type QString problematicString inf
  • 如何消除 QTableWidget 中的空白?

    How do I get rid of the whitespace in my application 我想摆脱 QTableWidget 中的空白 蓝色箭头 我该怎么做 这是我的应用程序的代码 gridLayout QGridLayou
  • 在 Qthread 中运行函数 - 应用程序将挂起

    我在 QT 内部线程方面遇到一些问题 include
  • QWebSocketServer - 不释放内存

    首先 我在安全 websocket 服务器应用程序上运行 valgrind 并发现了一个问题 在 Qt Memcheck 中我必须检查 外部错误 看到它 一些字节是肯定输了 指着我的main就在我的地方QCoreApplication ex
  • 面向 Delphi 开发人员的 Qt

    有人知道为 Delphi C Builder VCL 开发人员解释 Qt 的书籍或教程吗 对于具有该背景的开发人员来说 学习 Qt 的最佳方法是什么 我对如何使用 Qt 完成我知道如何在 Delphi 中完成的事情特别感兴趣 例如 Qt 相
  • QWinTaskbarProgress 不会显示

    我使用的是windows7和Qt5 3 0 我在 MainWindow 的构造函数中添加了以下内容 但任务栏上没有显示任何内容 我错过了什么 QWinTaskbarProgress pTaskbarProgress new QWinTask
  • 包含 Qt 标头的正确方法是什么?

    到目前为止我知道几种方法 includeQt 类 include
  • QChart 对大数据集无响应

    我的这段代码适用于高达 1000 的数据大小 现在我用 65536 个点对其进行了测试 series new QLineSeries QList

随机推荐

  • 如何通过Geth、Node.js和UNIX/PHP访问以太坊节点

    本文旨在说明通过Geth Node js如何访问以太坊节点和UNIX下PHP如何访问以太坊节点 说明如何通过RPC使用此 A 以太坊节点 对于以太坊主网络使用RPC url http 85 214 51 53 8545 对于Ropsten测
  • 线上生产问题系列之-@Async使用不当引发的血案

    现象描述 突然客户群里反馈 线上某功能处理出现严重拥堵 再处理不好就要切换渠道 这个功能就是一个通知功能 客户依赖通知结果去完成他的业务逻辑 但是这个通知非常缓慢 严重拥堵 背景描述 常有这样一个需求场景 为了提高请求的吞吐量 在一个请求链
  • 奇偶调序

    题目描述 输入一个整数数组 调整数组中数字的顺序 使得所有奇数位于数组的前半部分 所有偶数位于数组的后半部分 要求时间复杂度为O n 分析与解法 最容易想到的办法是从头扫描这个数组 每碰到一个偶数 拿出这个数字 并把位于这个数字后面的所有数
  • Scala针对容器的操作(遍历、映射、过滤、归约)案例

    Scala针对容器的操作 遍历 映射 一 遍历操作 二 映射操作 2 1 map方法 2 2 flatmap方法 三 过滤操作 四 归约操作 一 遍历操作 Scala容器的标准遍历方法foreach def foreach U f Elem
  • react+ts+echarts5.x按需导入实现世界地图

    registerMap注册世界地图 1 获取世界地图geoJSON格式的文件 获取地图的渠道 这个步骤很重要 本人找了很久都没找到世界地图的GeoJSON文件 这个网址可以提供 并且也提供了各个国家的GeoJSON a 根据 在线实例 确定
  • 前端js采坑,一个函数中同时有多个ajax()异步请求

    在近期的项目中 问题 多个异步请求执行时 有两个请求的路径是相同的 导致结果只执行当中的一个异步请求 add function vm showList false vm title 新增 vm role deptName null dept
  • 微服务架构-Day7

    学习目标 学会微服务架构 对应项目hotel demo 学习笔记 1 数据聚合 聚合 aggregations 可以让我们极其方便的实现对数据的统计 分析 运算 实现这些统计功能的比数据库的sql要方便的多 而且查询速度非常快 可以实现近实
  • display设为inline-block时引发的高度问题,大坑

    今天在写小程序 点击让这个遮罩层显示 结果一直下移 莫名其妙 解决方案 在元素的CSS中添加 vertical align bottom
  • SQL-使用视图

    什么是视图 它们怎样工作 何时使用它们 如何利用视图简化执行的某些SQL操作 1 使用视图的原因 A 重用SQL语句 B 简化复杂的SQL操作 在编写查询后 可以方便地重用它而不必知道其基本查询 C 使用表的一部分而不是整个表 D 保护数据
  • 【Python】科学计算库Scipy简易入门

    0 导语 Scipy是一个用于数学 科学 工程领域的常用软件包 可以处理插值 积分 优化 图像处理 常微分方程数值解的求解 信号处理等问题 它用于有效计算Numpy矩阵 使Numpy和Scipy协同工作 高效解决问题 Scipy是由针对特定
  • vue-组件按需加载

    组件按需加载 路由配置 path name component gt import views vue 按需加载 在vue中配置路由时 可以在头部先引入组件 然后下面定义路由时 在指向到具体使用的组件 这种是页面运行时 组件全部加载 占内存
  • 严重: 子容器启动失败 java.util.concurrent.ExecutionException 信息: 正在摧毁协议处理器 ["http-nio-80"]WARNING: An illegal

    话不多说直接上错误 解决方案 由于一开始以为是tomcat和eclipseEE出现故障 将两个软件重新下载并配置环境但错误没有解决 然后又检查了JDK版本也没问题 最后肯定了是代码的问题 仔细检查后发现是servlet映射地址写重了 后来又
  • HAL库的RCC简介

    一 RCC的时钟树总览 时钟输入源有四个 选择器 预 分频器和倍频器 最终设置的频率 SYSCLK系统时钟 SYSCLK可以有三种方式得到 1 HSI内部高速时钟用的是RC振荡器 频率为8M 精度不高 没有经过分频器和倍频器 这种方式得到的
  • 空utf8文件占三字节的问题(Java空文本文件FileInputStream读取问题)

    1 文件创建情况 2 程序代码 public class Demo01 public static void main String args throws IOException File file new File a txt long
  • pycharm mysql 安装_pycharm安装mysql驱动包

    新的环境配置pycharm的项目时 发现pycharm不能连接到mysql数据库 由于安了java环境但是还没配置相关的库 并且jetbrains家的IDE一般都是java写的 于是猜想可能是java缺少mysql的驱动 1 先确保pyth
  • c++学习:2.变量声明和定义的关系

    为了支持分离式编译 c 语言将声明和定义区分开来 声明只有名字并无实体 定义创建于声明名字相关的实体 因此声明和定义最重要的区别 声明不申请存储空间 定义申请存储空间 变量能且只能被定义一次 但是可以被多次声明 注意这里说的变量定义和变量赋
  • Pytorch 自己搭建的一个神经网络

    目录 数据集 dogs Vs Cats import time import torch nn as nn import torch optim from torch autograd import Variable from torch
  • 数学建模之圈养湖羊的空间利用率

    数学建模之圈养湖羊的空间利用率 D题最新最全思路已出 欢迎后台私信咨询 1 问题 规模化的圈养养殖场通常根据牲畜的性别和生长阶段分群饲养 适应不同种类 不同阶段的牲畜对空间的不同要求 以保障牲畜安全和健康 与此同时 也要尽量减少空间闲置所造
  • 使用 Redis 统计在线用户人数

    在构建应用的时候 我们经常需要对用户的一举一动进行记录 而其中一个比较重要的操作 就是对在线的用户进行记录 本文将介绍四种使用 Redis 对在线用户进行记录的方案 这些方案虽然都可以对在线用户的数量进行统计 但每个方案都有一些自己特有的操
  • QT 学习笔记(十)

    文章目录 一 绘图 1 理论知识储备 2 画背景图 3 简单绘图 4 手动刷新窗口 二 绘图实现代码 1 主窗口头文件 widget h 2 主窗口头文件 widget cpp 由于每次代码都是在原有程序上修改 因此除了新建项目 不然一般会