Qt常用控件之显示类控件

news2025/1/12 19:06:17

目录

QLabel

文本格式

设置图片

文本对齐/自动换行/边距/缩进

设置伙伴

QLCDNumber

倒计时功能

QProgressBar

进度条

QCalendarWidget


QLabel

QLabel 同样是 QWidget 的子类,所以前面博客中 QWidget 中的属性方法也是适用的

QLabel可以用来显示文本和图片
核心属性如下:

           属性                                                          说明
           textQLabel中的文本
      textFormat文本的格式
Qt::PlainText 纯文本 (使用最多)
Qt::RichText 富文本(支持 html 标签)
Ot::MarkdownText markdown 格式
Qt::AutoText 根据文本内容自动决定文本格式
         pixmapQLabel 内部包含的图片
  scaledContents设为 true 表示内容自动拉伸填充 QLabel
设为 false 则不会自动拉伸
       alignment对齐方式,可以设置水平和垂直方向如何对齐
       wordWrap设为 true 内部的文本会自动换行
设为 false 则内部文本不会自动换行 (QLabel不提供滚动条,QTestEdit会提供)
          indent设置文本缩进,水平和垂直方向都生效
          margin内部文本和边框之间的边距
不同于于 indent,但是是上下左右四个方向都同时有效
而 indent 最多只是两个方向有效(具体哪两个方向有效取决于 alignment)
openExternalLinks是否允许打开一个外部的链接
(当 OLabel文本内容包含 url 的时候涉及到)
          buddy给 OLabel关联一个 "伙伴",这样点击 OLabel时就能激活对应的伙伴
例如伙伴如果是一个 QCheckBox,那么该 QCheckBox 就会被选中

文本格式

下面演示 QLabel 的 textFormat 属性,先创建三个 Label 标签:

再将这三个文本分别设置为纯文本、富文本、markdown文本:

可以看到,给这三个不同 textFormat 属性的文本的 Test,分别加入 html 标签、markdown格式,运行程序,结果如下:

所以得出结论,纯文本不会识别 html 标签或是 markdown格式,只会将他们当做文本打印出来


设置图片

想要设置图片,当然要使用 qrc机制,这里就不重复步骤了:

接着图形化界面的方式,拖动一个 Label,并编写构造函数:

此时运行程序:

我们发现图片并没有按照我们代码所编写的那样,让整个 Label 都是这个图片,是因为我们在 qrc 中传入的图片,可能原本的尺寸就是比较小的,像上述所插入的 dog.png 原本尺寸就是 200 * 200 的,而 Widget 窗口是 800* 600 的,所以不能够显示整个屏幕

     

而我们想要让整个 Widget 窗口都显示图片,就需要将 scaledContents 属性设置为 true,自动拉伸图片:

此时运行程序,dog.png 就能够填满整个屏幕了:

在上面代码中是在构造函数里,进行的这样的尺寸设置这个设置相当于是一次性的
一旦程序运行起来之后,QLabel 的尺寸就固定下来了,如果窗口发生改变,QLabel 是不会变化的

如果想要 QLabel 随着窗口大小实时发送改变,就需要了解 事件

在前面的学习中,我们了解了用户的操作,会对应一些信号
在 Qt 中,表示用户的操作,有两类概念,一个是信号,另一个是事件

当用户拖拽修改窗口大小的时候,就会触发 resize 事件(resizeEvent)
像 resize 这样的事件,是连续变化的,把窗口尺寸从 A 拖到 B 这个过程中,会触发出一系列的 resizeEvent

此时就可以借助 resizeEvent 来完成上述的功能
可以让 Widget 窗囗类,重写父类(QWidget)的 resizeEvent 虚函数,在鼠标拖动窗口尺寸的过程中,这个函数就会被反复调用执行,每次触发一个 resizeEvent 事件,都会调用一次对应的虚函数

由于此处进行了函数重写,调用父类的虚函数就会实际调用到子类的对应的函数(多态)

下面先在 widget.h 中,声明需要重写的 resizeEvent 函数:
这里的形参 event 是非常有用的,这里就包含了触发这个 resize 事件这一时刻,窗口的尺寸的数值

再在 widget.cpp 中编写 resizeEvent 函数,观察拖动窗口时发送的情况:

运行程序:

此时拖动窗口,发现 Qt 会自动调用 resizeEvent 函数,所以我们这里重写虚函数,是指定了一个回调函数的逻辑:

在实际编程中,指定回调函数其实有很多种写法:

  • 设置函数指针
  • 设置仿函数(函数对象)
  • 设置 lambda
  • 通过重写父类虚函数(框架中拿着父类的指针调用这个函数,如果你创建了子类重写了这个函数此时在多态机制下,实际执行的就是子类的函数了)
  • Qt 的信号槽

上面只是单纯的打印出尺寸,下面完善代码,使得能够通过实时窗口大小的结果,来实时修改 QLabel 的尺寸:

运行程序,随意拖动窗口的大小,图片也会实时改变,满足了我们的需求:


文本对齐/自动换行/边距/缩进

文本对齐

我们创建一个 Label,并在右侧找到 QFrame,设置 Label 的边框,这样能够更加清楚的观察文本对齐的方式

我们将 第一个属性 frameShape 改为 box,此时就有边框了:

下面给第一个 Label 设置属性,将其设置为 水平居中(AlignHCenter)和垂直居中(AlignVCenter)

之所以中间使用 按位或 连接,因为这里的 AlignHCenter 和 AlignVCenter 都是枚举类型:
类似于位图一样的效果,想要某个效果,就将某个比特位置为1即可

此时运行程序:

如果水平和垂直方向不居中了,想让它靠右上角对齐,将 AlignHCenter 改为 AlignRight,AlignVCenter 改为 AlignTop 即可:


自动换行

给第二个 Label 设置一段很长的文本:

运行程序观察:

发现这段文本无法完全显示出来,所以给它添加上自动换行的属性:


缩进

缩进使用的属性是 indent:

此处设置的缩进即使文本换行了,后续的行也会产生缩进不仅仅是首行缩进:


边距

边距是会影响上下左右四个方向的,用到了 margin 属性:

可以看到设置完边距50,这段长文本有一部分被覆盖掉了,显示不太清晰,超出部分也不再显示了,这就是设置边距的效果


设置伙伴

可以将 QLabel 和 单选框/复选框 绑定一个伙伴关系,此时就能够通过 QLabel 触发 单选框/复选框 的选择操作

下面先创建两个 RadioButton,分别在这两个 RadioButton 后面跟上一个 Label:

此时在构造函数中,将 Label 与对应的 RadioButton 建立伙伴关系:

运行程序,不需要鼠标点击,使用 alt + a / alt + b 就能选中对应的 单选按钮/复选按钮:

Qt 中,QLabel 中写的文本,是可以指定快捷键的,此处快捷键的规则功能上要比 QPushButton 弱很多
是在文本中使用 & 跟上一个字符来表示快捷键
比如 &A => 通过键盘上的 alt +a来触发这个快捷键
        &B =>通过键盘上的 alt +b 来触发
绑定了伙伴关系之后,通过快捷键就可以选中对应的 单选按钮/复选按钮


QLCDNumber

QLCDNumer 是一个专门用来显示数字的控件,类似于"老式计算器"的效果

核心属性:

           属性                                                          说明
        intValueQLCDNumber 显示的数字值(int)
         valueQLCDNumber 显示的数字值(double) 和 intValue 是联动的
例如给 value 设为 1.5,intValue 的值就是 2
另外,设置 value和 intValue 的方法名字为 display,而不是 setValue 或者 setIntValue 
     digitCount显示几位数字
         mode数字显示形式
QLCDNumber::Dec:十进制模式,显示常规的十进制数字
QLCDNumber::Hex:十六进制模式,以十六进制格式显示数字
QLCDNumber::Bin:二进制模式,以二进制格式显示数字
QLCDNumber::0ct:八进制模式,以八进制格式显示数字
只有十进制的时候才能显示小数点后的内容
    segmentStyle设置显示风格
QLCDNumber::Flat:平面的显示风格,数字呈现在一个平坦的表面上QLCDNumber::0utline:轮廓显示风格,数字具有清晰的轮和阴影效果
5QLCDNumber::Filled:填充显示风格,数字被填充颜色并与背景区分开
smallDecimalPoint设置比较小的小数点

倒计时功能

使用 QLCDNumber 显示一个初始的数值,比如 10
每隔一秒钟,数字就 -1,一直到 0,就停止了

先使用 图形化界面 的方式拖动一个 LCDNumber:

此处关键要点是要实现"每秒钟 -1"这个效果
周期性的执行某个逻辑,也就是"定时器”
C++标准库中,没有提供定时器的实现,Boost 里面提供了对应的功能

Qt 中也封装了对应的定时器(结合了信号槽机制的)
Qt 中是使用 QTimer类,通过这个类创建出来的对象,就会产生一个 timeout 这样的信号
可以通过 start 方法来开启定时器,并且参数中设定触发 timeout 信号的周期
再结合 connect,把这个 timeout 信号绑定到需要的槽函数中,就可以执行逻辑,修改 LCDNumber 中的数字了

先在 widget.h 中添加成员 timer 和 槽函数 handle:

再在 widget.cpp 中编写代码:

此时运行程序,完成了倒计时功能:


上面实现的 倒计时功能 是利用的 QTimer类, 那么如果不使用这个类,直接写一个循环,每个一秒减一,能够实现倒计时的功能吗,看下面的示例

我们直接在 ui界面 中,在右侧修改初始值:

之前学习 C++ 时使用 sleep函数 是 Windows 的 API,需要在 VS 中包含 Windows.h 的头文件才能使用,而 Qt 是无法直接使用 Windows.h 这个头文件的
所以下面采用 thread库 中的 sleep_for 来完成休眠一秒的操作

具体代码如下:

 

此时运行程序,发现10秒内并没有显示窗口,而是10秒后,才会显示下面的界面:

这是因为我们是在构造函数中编写的上述代码,而 main.cc 在执行的时候,构造函数执行完,才会执行 show函数,所以运行程序后,无法看到窗口,直到在构造函数中10秒执行完,才显示0秒的界面


下面我们就可以思考一下,另一个情况能够实现吗
假设在构造函数中,另外创建一个线程,在新的线程中,执行上述循环+更新操作,此时并不影响主线程的构造函数的执行
所以将代码改为:

此时运行程序,发现控制台上日志显示,程序终止,出现异常:

而之所以出现异常,原因是:
Qt 里,界面有一个专门的线程去负责维护更新的(主线程,也就是 main 函数所在的线程)
对于 GUI 来说,内部包含了很多的隐藏状态,Qt 为了保证修改界面的过程中,线程安全是不会受到影响的,所以 Qt 禁止了其他线程直接修改界面

而我们上面创建一个线程,在最后一行的 ui->lcdNumber->display(value); 就是在修改界面,所以会出现异常

因此 Qt 为了确保线程安全,直接要求所有的对界面的修改操作,必须在主线程中完成
对于 Qt 的槽函数来说,默认情况下,槽函数都是由主线程调用的,所以在槽函数中修改界面是没有任何问题的


QProgressBar

使用 QProgressBar 表示一个进度条

核心属性:

                属性                                  说明
            minimum进度条最小值
            maximum进度条最大值
               value进度条当前值
           alignment文本在进度条中的对齐方式
Qt::AlignLeft:左对齐
Qt::AlignRight:右对齐
Qt::Aligncenter:居中对齐
Qt::AlignJustify:两端对齐
          textVisible进度条的数字是否可见
          orientation进度条的方向是水平还是垂直
     invertAppearance是否是朝反方向增长进度
         textDirection文本的朝向
              format展示的数字格式
%p:表示进度的百分比 (0-100)
%v:表示进度的数值 (0-100)
%m:表示剩余时间 (以毫秒为单位)
%t:表示总时间 (以毫秒为单位)

进度条

创建一个进度条,让这个进度条的进度跟随时间增长
(可以假设每隔 100ms,让进度条数值+1)

先拖拽一个 进度条:


通过右边的属性栏,将最小值/最大值设置为0/100,将当前值设置为0


下面就需要上面设计倒计时功能时,所用到的 QTimer类

同样在 widget.h 中新增成员 timer,新增槽函数 handle:
之所以需要定义一个成员 timer,而不是在构造函数中定义局部变量,是因为下面的槽函数 handle 还需要使用 timer

widget.cpp:

运行程序,进度条以 100ms 的速度每次 +1


这里有一个细节问题,我们所使用的 QTimer类,是需要包含头文件的,我们之前在写 C++代码 时一般是包含在 .h文件 中的,而在 Qt 中,既可以在 .h 中包含,也可以在 .cpp 中包含

之所以可以不在 .h 中包含,却能够在 .h 中声明 QTimer类,是因为:
在 Qt 中,有一个专门的头文件,这个头文件中包含了 Qt 中所有类的"前置声明",这个头文件一般不会直接接触到,但是包含其他的 Qt 的头文件,例如 #include<QWidget> 都会间接的包含到这个头文件

Widget 类的前面已经提供了 QTimer 类的声名的话,此时就可以在 Widget.h 中声明 QTimer 的指针/引用类型的成员
后续如果要真正使用 QTimer(包括创建实例,使用里面的成员),仍然需要包含 QTimer 的头文件(包含了 QTimer 的详细的类的定义)

Qt 使用上述的技巧,主要解决的是编译速度的问题

C++编译速度慢,和 #include 头文件有直接关系的
由于 include 关系错综复杂,因此尽可能减少 include 头文件的个数,就可以有效的减少编译时间
Qt 中就使用 class 前置声明的方式,来尽量减少头文件的包含,通过前置声明的方式,Qt 中的每个头文件包含的其他头文件数量都能得到一定的降低

但是咱们实际开发中,还是要该包含就包含,与其通过特殊技巧来缩短编译时间,不如说引入更好的硬件资源,来更高效的编译
例如:一些互联网大厂,都有专门的"编译集群”(分布式编译)

正是因为 #include 编译速度慢的原因,所以在 C++ 20 标准开始,就引入了"模块" module来替代 #include


因为 QProgressBar 也是 QWidget 的子类,所以 QWidget 的 styleSheet 属性也就可以使用,所以我们可以将 进度条 的颜色改为红色:
先拖动一个进度条:

右键,点击改变样式表:

输入以下内容:

此时进度条颜色就变为红色了,但是我们发现 24% 原来是在右边,现在却在左上角了:

这种情况有可能是 Qt 的 bug,并不知道原因是什么,但是也没关系,我们也可以设置样式:

此时就变为 垂直/水平方向 都 居中对齐了:

进度条具体的进度如何设置,一般都是根据实际的任务类型来灵活设置的
例如:要读取一个很大的文件,就可以先获取到文件的总大小,每读取一部分数据(可以计算出读了多少数据的),更新一次进度条的数值
设置进度条的过程中,往往是要搭配 定时器 的


QCalendarWidget

QCalendarwidget 表示一个"日历",形如

核心属性:

属性说明
selectDate当前选中的日期
minimumDate最小日期
maximumDate最大日期
firstDayOfWeek每周的第一天(也就是日历的第一列) 是周几
gridVisible是否显示表格的边框
selectionMode是否允许选择日期
navigationBarVisible日历上方标题是否显示
horizontalHeaderFormat日历上方标题显示的日期格式
verticalHeaderFormat日历第一列显示的内容格式
dateEditEnabled是否允许日期被编辑

重要信号

                      信号                                                说明
selectionChanged(const QDate&)当选中的日期发生改变时发出
activated(const QDate&)当双击⼀个有效的日期或者按下回车键时发出,形参是⼀个QDate类型,保存了选中的日期
currentPageChanged(int, int)当年份月份改变时发出,形参表示改变后的新年份和月份

首先使用 图形化界面 的方式,拖动一个 QCalendarWidget 和一个 Label,用于显示我们选中的日期:

接着右键日历,选择 转到槽 的 selectionChanged:

下面编写 槽函数 :

运行程序,可以看到控制台会打印我们所点击的日期,上面的 Label 中也会显示所点击的日期:


Qt常用控件之显示类控件到此结束啦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249808.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

架构-微服务-环境搭建

文章目录 前言一、案例准备1. 技术选型2. 模块设计3. 微服务调用 二、创建父工程三、创建基础模块四、创建用户微服务五、创建商品微服务六、创建订单微服务 前言 ‌微服务环境搭建‌ 使用的电商项目中的商品、订单、用户为案例进行讲解。 一、案例准备 1. 技术选型 maven&a…

【JTAG】1149.6协议总结

【JTAG】1149.6协议详解-CSDN博客 IEEE 1149.6标准的基本实现需要在信号路径驱动器中添加一个时脉产生器&#xff0c;它能发射单一脉冲或一列脉冲&#xff0c;这取决于被加载到 1149.1 指令暂存器中的 EXTEST_PULSE 或 EXTEST_TRAIN 指令。1149.6在克服信道中共模讯号干扰能力…

小程序 - 个人简历

为了让招聘人员快速地认识自己&#xff0c;可以做一个“个人简历”微信小程序&#xff0c; 展示自己的个人信息。 下面将对“个人简历”微信小程序进行详细讲解。 目录 个人简历 创建图片目录 页面开发 index.wxml index.wxss 功能实现截图 总结 个人简历 创建图片目录…

Tülu 3:重新定义开源大模型的后训练范式

一、引言 在大型语言模型&#xff08;LLM&#xff09;的发展历程中&#xff0c;预训练阶段往往受到最多关注&#xff0c;动辄需要数百万美元算力投入和数万亿token的训练数据。然而&#xff0c;一个鲜为人知但同样关键的事实是&#xff1a;预训练完成的模型实际上并不能直接投…

systemverilog约束中:=和:/的区别

“x dist { [100:102] : 1, 200 : 2, 300 : 5}” 意味着其值等于100或101或102或200或300其中之一&#xff0c; 其权重比例为1:1:1:2:5 “x dist { [100:102] :/ 1, 200 : 2, 300 : 5}” 意味着等于100&#xff0c;101&#xff0c;102或200&#xff0c;或300其…

用Pycharm安装manim

由于版本和工具的差异&#xff0c;manim的安装方式不尽相同。本文用Pycharm来安装manim. 一、准备工作&#xff1a;安装相应版本的python、pycharm和ffmpeg. 此处提供一种安装ffmpeg的方式 下载地址&#xff1a;FFmpeg 下载后&#xff0c;解压到指定目录。 配置环境变量&am…

云GPU——pycharm远程连接featurize实例

点击PyCharm远程连接会有详细的教程&#xff0c; 本文补充虚拟环境的创建以及包的下载。 1、虚拟环境的创建&#xff1a; 2、虚拟环境创建好之后&#xff0c;下载需要的包 &#xff08;这种方法比较快&#xff09; 可以在python interpreter点击go to tool window&#xff0c…

Fanuc法那科机器人维修之参考位置详解

参考位置是预先设定好的一个或多个特定点位&#xff0c;当启用这一功能时&#xff0c;系统会实时且精确地判断机器人的当前关节角度是否处于预设参考位置的一定范围之内&#xff08;这个范围区间是可以根据实际需求进行设置的&#xff09;&#xff0c;并据此输出指定的信号。 这…

混淆零碎知识点

minifyEnabled true //混淆开关 zipAlignEnabled true // Zipalign优化 shrinkResources true // 移除无用的resource文件 &#xff08;必须要混淆开了之后才才可以设置为true&#xff09; proguard-rules.pro 为混淆文件 //整个文件保留 不被混淆 -keep class com.cn…

ELK(Elasticsearch + logstash + kibana + Filebeat + Kafka + Zookeeper)日志分析系统

文章目录 前言架构软件包下载 一、准备工作1. Linux 网络设置2. 配置hosts文件3. 配置免密登录4. 设置 NTP 时钟同步5. 关闭防火墙6. 关闭交换分区7. 调整内存映射区域数限制8. 调整文件、进程、内存资源限制 二、JDK 安装1. 解压软件2. 配置环境变量3. 验证软件 三、安装 Elas…

【通信协议】CAN总线通信协议的学习(一)基础理论知识学习

目录 1、CAN基本概念 1.0、基本概念 1.1、与其他通信协议的区别 1.2、CAN硬件电路 1.3、CAN总线电平信号 1.4、CAN的差分信号 1.5、CAN总线工作原理 1.6、CAN协议物理层 2、数据帧结构 3、CAN参数配置&#xff0c;波特率计算 1、CAN基本概念 CAN&#xff1a;controll…

探索文件系统,Python os库是你的瑞士军刀

文章目录 探索文件系统&#xff0c;Python os库是你的瑞士军刀第一部分&#xff1a;背景介绍第二部分&#xff1a;os库是什么&#xff1f;第三部分&#xff1a;如何安装os库&#xff1f;第四部分&#xff1a;简单库函数使用方法1. 获取当前工作目录2. 改变当前工作目录3. 列出目…

QT6学习第六天 初识QML

QT6学习第六天 创建Qt Quick UI项目使用Qt Quick DesignerQML 语法基础 创建Qt Quick UI项目 如果你有只测试QML相关内容快速显示界面的需求&#xff0c;这时可以创建Qt Quick UI 项目&#xff0c;该项目中只包含 QML 和 JavaScript 代码&#xff0c;没有 C 代码。 对于 QML …

深入浅出剖析典型文生图产品Midjourney

2022年7月,一个小团队推出了公测的 Midjourney,打破了 AIGC 领域的大厂垄断。作为一个精调生成模型,以聊天机器人方式部署在 Discord,它创作的《太空歌剧院》作品,甚至获得了美国「数字艺术/数码摄影」竞赛单元一等奖。 这一事件展示了 AI 在绘画领域惊人的创造力,让人们…

评分规则的建模,用户全选就是满分10分(分数可自定义), 选2个5分, 选2个以下0分

子夜(603***854) 15:11:40 和各位讨论一下设计问题: 有个有业务场景: 有一组产品共4个产品(数目用户可自定义), 需要一套规则,比如如果用户全选就是满分10分(分数可自定义), 选2个5分, 选2个以下0分 又比如另一组产品 产品有个必选属性,如果选了其中所有的必选则5分, 其他项每1…

水体分割检测 包含YOLOV,COCO,VOC三种标记的数据集包含 857张图片

说明 水体分割检测指的是利用深度学习模型进行水体区域的分割和检测。YOLO&#xff08;You Only Look Once&#xff09;是一种流行的实时目标检测算法&#xff0c;其主要特点是速度快&#xff0c;适合于实时场景下的目标检测。 在水体分割检测中&#xff0c;可以使用YOLO算法来…

【新人系列】Python 入门(十四):文件操作

✍ 个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4dd; 专栏地址&#xff1a;https://blog.csdn.net/newin2020/category_12801353.html &#x1f4e3; 专栏定位&#xff1a;为 0 基础刚入门 Python 的小伙伴提供详细的讲解&#xff0c;也欢迎大佬们…

OGRE 3D----2. QGRE + QQuickView

将 OGRE(面向对象图形渲染引擎)集成到使用 QQuickView 的 Qt Quick 应用程序中,可以在现代灵活的 UI 框架中提供强大的 3D 渲染功能。本文将指导您如何在 QQuickView 环境中设置 OGRE。 前提条件 在开始之前,请确保您已安装以下内容: Qt(版本 5.15 )OGRE(版本14.2.5)…

丹摩 | 利用 CogVideoX 生成视频

声明&#xff1a;非广告&#xff0c;纯用户体验 1. CogVideoX CogVideoX 是智谱 AI 推出的一款极具创新性与突破性的视频生成产品。它在技术层面展现出诸多卓越特性&#xff0c;例如其采用的 Diffusion Transformer&#xff08;DiT&#xff09;架构奠定了强大的生成能力基础…

本地化部署 私有化大语言模型

本地化部署 私有化大语言模型 本地化部署 私有化大语言模型Anaconda 环境搭建运行 代码概述环境配置安装依赖CUDA 环境配置 系统设计与实现文件处理与加载文档索引构建模型加载与推理文件上传与索引更新实时对话与文档检索Gradio 前端设计 主要功能完整代码功能说明运行示例文件…