【Qt】控件概述(3)—— 显示类控件

显示类控件

  • 1. QLabel——标签
    • 1.1 setPixmap设置图片
    • 1.2 setAlignment设置文本对齐方式
    • 1.3 setWordWrap设置自动换行
    • 1.4 setIndent设置缩进
    • 1.5 setMargin设置边距
    • 1.6 body
  • 2. QLCDNumber
    • 2.1 使用QTimer实现一个倒计时效果
    • 2.2 使用循环的方式实现倒计时
  • 3. QProgressBar——进度条
  • 4. QCalendarWidget——日历

1. QLabel——标签

QLabel可以用来显示文本和图片:

属性说明
textQLabel中的文本
textFormat文本格式:1:Qt::PlaintText纯文本,2:RichText富文本,3:MarkDownText markdown格式,4:Qt:AutoText根据文本内容自动决定文本格式
pixmapQLabel内的图片
scaldContents设置未true表示自动拉伸填充QLabel,设置为false则不会自动填充
alignment表示对齐方式,可以设置为水平对齐和垂直对齐
wordWrap自动换行设置,设置为true表示开启,设置为false表示不开启
indent文本缩进,水平和垂直都可以生效
margin表示文本和边框之间的距离,在上下左右四个方向生效
openExternalLinks是否允许打开一个外部链接(当Qlabel涉及到url的时候)
buddy给QLabel关联一个“伙伴”,当点击QLabel时就会激活对应的“伙伴”

1.1 setPixmap设置图片

代码样例:Label显示图片
虽然前面讲的QPushButton也可以通过setIcon的方式进行添加图片,但是大多数时候我们更希望使用QLabel来进行添加一个更单纯的一个图片。

  1. 首先同样讲图片以qrc的方式添加到Qt中
  2. 创建Label,并可以通过pixmap进行添加图片
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QLabel* label = new QLabel(this);// 设置标签的大小和Widget窗口的大小是一样的QRect rect = this->geometry();label->setGeometry(0, 0, rect.width(), rect.height());// 插入图片并设置图片大小QPixmap pixmap(":/qt.jpg");pixmap = pixmap.scaled(rect.width(), rect.height());// 也可以直接使用自动填充,让图片自动贴合标签的大小// label->setScaledContents(true);label->setPixmap(pixmap);
}

但是这个时候我们是可以对Widget的窗口进行调整大小的,而在我们进行调整大小的时候,我们的标签是不会跟着改变的,所以这里我们需要提供一个事件。也就是说当我们在调整Widget的时候QWidget会触发一个事件resizeEvent事件,也就是说当Widget窗口大小发生变化的时候QWidget 会自动进行调用,而这个时候我们想要Widget进行调用,就可以在Widget中重写这个resizeEvent实现多态,这样只要窗口发生变化就会通过多态调用Widget中的resizeEvent(这个事件我们后面会详细进行讲解),所以我们就可以自定义函数来完成这一操作。

在这里插入图片描述

// 在widget.h中添加函数声明
void resizeEvent(QResizeEvent *event); // 这个是QWidget中有的
void Widget::resizeEvent(QResizeEvent *event)
{label->setGeometry(0, 0, event->size().width(), event->size().height());label->setScaledContents(true);qDebug() << event->size();
}

1.2 setAlignment设置文本对齐方式

首先为了我们方便观察,我么需要给label设置一个外边框,我们可以在ui界面中进行设置。
在这里插入图片描述

QFrame是QLabel的父类,其中frameShape属性用来设置边框属性。

  • QFrame::Box :矩形边框
  • QFrame::Panel :带有可点击区域的⾯板边框
  • QFrame::WinPanel :Windows风格的边框
  • QFrame::HLine :水平线边框
  • QFrame::VLine :垂直线边框
  • QFrame::StyledPanel :带有可点击区域的⾯板边框,但样式取决于窗口主题
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->label->setText("这是一个水平居中和垂直居中");// 设置文本的对齐方式// 设置方式 水平方向 | 垂直方向ui->label->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
}

而设置垂直方向和水平方向的对齐方式其实就是宏。

enum AlignmentFlag {AlignLeft = 0x0001, AlignLeading = AlignLeft,AlignRight = 0x0002,AlignTrailing = AlignRight,AlignHCenter = 0x0004,AlignJustify = 0x0008,AlignAbsolute = 0x0010,AlignHorizontal_Mask = AlignLeft | AlignRight | AlignHCenter | AlignJustify | AlignAbsolute,AlignTop = 0x0020,AlignBottom = 0x0040,AlignVCenter = 0x0080,AlignBaseline = 0x0100,// Note that 0x100 will clash with Qt::TextSingleLine = 0x100 due to what the comment above// this enum declaration states. However, since Qt::AlignBaseline is only used by layouts,// it doesn't make sense to pass Qt::AlignBaseline to QPainter::drawText(), so there// shouldn't really be any ambiguity between the two overlapping enum values.AlignVertical_Mask = AlignTop | AlignBottom | AlignVCenter | AlignBaseline,AlignCenter = AlignVCenter | AlignHCenter};

在这里插入图片描述

1.3 setWordWrap设置自动换行

如果我们使用在label中输入了一行很长的文本而没有自动换行,就会导致部分文本被覆盖而无法显示。

ui->label->setText("这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,");

在这里插入图片描述

ui->label->setText("这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,");
ui->label->setWordWrap(true);

在这里插入图片描述

1.4 setIndent设置缩进

一般我们在书写word的时候使用的都是首行缩进,但是在Qt中,这里的缩进是对所有行都适用的,不单单是首行缩进

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->label->setText("这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,");ui->label->setWordWrap(true);ui->label->setIndent(50); // 单位像素
}

在这里插入图片描述

1.5 setMargin设置边距

我们先直接讲对齐方式改为水平左对齐,垂直上对其。

ui->label->setText("这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,");
ui->label->setWordWrap(true);
ui->label->setAlignment(Qt::AlignLeft | Qt::AlignTop);

在这里插入图片描述
设置margin后

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->label->setText("这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,这是一个自动换行机制,");ui->label->setWordWrap(true);ui->label->setAlignment(Qt::AlignLeft | Qt::AlignTop);ui->label->setMargin(20);
}

在这里插入图片描述

1.6 body

我们可以创建两个label和两个radioButton,将其两两关联。然后可以使用快捷键的方式进行选择。
在这里插入图片描述

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->label->setBuddy(ui->radioButton);ui->label_2->setBuddy(ui->radioButton_2);
}

这样就可以使用 alt + a选择1,alt+b选择2了。而如果想要做到这样的效果也需要遵循一些规则,也就是使用&A(& + 快捷键)这样的形式才可以做到。

2. QLCDNumber

QLCDNumber是一个专门用来显示数字的控件。

属性说明
intValueQLCDNumber显示数字的值(int)
valueQLCDNumber显示的数字值(double),和intValue是联动的,例如value为1.2,那么intValue就是1,另外value和intValue的方法名在位display,而不是setValue或者setValue了
digitCount显示数字的位数
mode显示数字的模式。1:QLCDNubmer::Dec,十进制。2:QLCDNubmer::Hex,十六进制。3:QLCDNubmer::Bin,二进制。4:QLCDNubmer::Oct,八进制。
segmentStyle设置显示风格,1:QLCDNumber::Flat,平面显示风格,数字呈现在一个平坦的表面上。2:QLCDNumber::Outline,轮廓显示风格,数字具有轮廓和阴影效果。3:QLCDNumber::Filled,填充风格,数字可以填充颜色与背景进行区分。

2.1 使用QTimer实现一个倒计时效果

代码样式:显示一个倒计时效果
在此之前介绍一个了QTimer类,这个类是Qt封装的一个定时器,可以通过start方法启动定时器,并通过传递参数的方式进行设定定时周期。而QTimer中有一个信号timeout,会根据周期定期的触发timeout信号,这样我们可以把周期设置为1秒,就可以首先一个简单的定时器了。

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 创建一个定时器类time = new QTimer(this);ui->lcdNumber->display(10);connect(time, &QTimer::timeout, this, &Widget::handle);// 启动定时器time->start(1000); // 单位毫秒
}Widget::~Widget()
{delete ui;
}void Widget::handle()
{// 获取当前lcdNumnber值int num = ui->lcdNumber->value();if (num <= 0){// 关闭定时器time->stop();return;}// 设置值ui->lcdNumber->display(num - 1);
}

2.2 使用循环的方式实现倒计时

针对上述存在两个问题。

  1. 我们先使用最为平常的for循环进行实现,使用Sleep的方式实现。而Sleep是windows的需要包含"windows.h",那是Qt并没有相关的api,但是C++11 中引路了sleep是thread库中的sleep_for
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->lcdNumber->display(10);int value = ui->lcdNumber->value();while(true){std::this_thread::sleep_for(std::chrono::seconds(1));if (value <= 0){break;}value -= 1;ui->lcdNumber->display(value);}
}

这样明显是没法显示出来的,因为whiel循环是在Widget的构造函数中实现的,而窗口的显示是在Widget类实例化后使用w.show()进行实现的,所以是等到while循环结束后,才会调用窗口显示函数进行窗口展示。

  1. 所以这里我们就想到使用子线程来进行修改
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->lcdNumber->display(10);std::thread t([this](){int value = ui->lcdNumber->value();while(true){std::this_thread::sleep_for(std::chrono::seconds(1));if (value <= 0){break;}value -= 1;ui->lcdNumber->display(value);}});
}

上述通过子线程的方式修改GUI上的内容同样是不行的,在Qt中规定,任何对GUI上内容的操作,必须是主线程中完成的。这样的约定主要是因为GUI中的状态往往是牵一发东全身,就需要同步的对其他内容进行调整。比如调整了某个元素的尺寸,就可能影响到内部的文字位置,或者其他元素的位置.这里⼀连串的修改,都是需要按照⼀定的顺序来完成的.由于多线程执行的顺序无法保障,因此Qt从根本上禁止了其他线程修改GUI状态,避免后续的⼀系列问题.

3. QProgressBar——进度条

核心属性:

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

代码样例:实现一个进度条

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);time = new QTimer(this);connect(time, &QTimer::timeout, this, &Widget::handle);time->start(100);
}Widget::~Widget()
{delete ui;
}void Widget::handle()
{int value = ui->progressBar->value();if (value >= 100){time->stop();return;}ui->progressBar->setValue(value + 1);
}

这里我们看到Widget.h这块

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void handle();private:Ui::Widget *ui;QTimer* time;
};
#endif // WIDGET_H

从上述代码中我们可以发现一个小细节,就是Widget.h中明明使用了QTimer类,但是并没有包含QTimer头文件#include < QTimer >,而且还没有编译报错。这是应为Qt做了一些特殊处理,在Qt中专门有一个头文件,这个头文件包含了Qt中所有类的“前置声明”形如(class QTimer; class QWidget……),而这个头文件一般不会直接接触到,而是包含在其他的Qt的头文件中,所以在继承的时候就间接的包含这个头文件,所以就可以使用一些类在头文件中声明各种类的指针或者了引用。

而这样的做的目的就是减少编译时的运行时间,应为在C/C++编译期间是要讲头文件进行展开的,而对于一个大型的项目来讲,不乏会包含大量的头文件,而这也间接的增加了编译的时间,所以在头文件声明之处就可以使用这样的前置声明的技术来减少头文件的包含,也可以做到间接减少编译的时间。

但是在C++20后就开始使用module来代替#include,这样也是为了减少编译时的时间消耗。

同样进度条也是可以设置样式的。可以通过ui界面的熟悉面板进行设置,也可以使用代码进行设置。
在这里插入图片描述

4. QCalendarWidget——日历

核心属性

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

重要信号

信号说明
selectionChanged(const QDate&)当选中的日期发生改变时发出
activated(const QDate&)当双击⼀个有效的日期或者按下回车键时发出,形参是⼀个QDate类型,保存了选中的日期
currentPageChanged(int, int)当年份月份改变时发出,形参表示改变后的新年份和月份
void Widget::on_calendarWidget_selectionChanged()
{QDate date = ui->calendarWidget->selectedDate();ui->label->setText(date.toString());
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

商贸物流痛点解析

商贸物流痛点解析 在当今全球化的商业环境中&#xff0c;商贸与物流之间的紧密协作已成为业务成功的关键因素。然而&#xff0c;许多组织面临着信息不对称、资源配套不足以及系统间隔离等痛点&#xff0c;这些问题严重阻碍了商贸体系与物流、仓储和园区的有效联动&#xff0c;…

Linux高效查日志命令介绍

说明&#xff1a;之前介绍Linux补充命令时&#xff0c;有介绍使用tail、grep命令查日志&#xff1b; Linux命令补充 今天发现仅凭这两条命令不够&#xff0c;本文扩展介绍一下。 命令一&#xff1a;查看日志开头 head -n 行数 日志路径如下&#xff0c;可以查看程序启动是否…

数据库SQL基础教程(二)

目录 连接(JOIN) 语法&#xff1a; 不同的 SQL JOIN INNER JOIN 关键字 LEFT JOIN 关键字 SQL LEFT JOIN 语法 RIGHT JOIN 关键字 SQL RIGHT JOIN 语法 FULL OUTER JOIN 关键字 SQL FULL OUTER JOIN 语法 UNION 操作符 SQL UNION 语法 SQL UNION ALL 语法 SELECT I…

uniapp引入ThorUI的方法

1、下载文件 2、复制相应的文件除了pages 3、往项目中复制即可 4、引入即可实现 5、添加easycome自动引入

单片机(学习)2024.10.9

目录 汇编整体分类 1.指令 2.伪操作 3.伪指令 汇编代码 汇编初始化 数据搬运指令 算术运算指令 加法 减法 乘法 比较指令 跳转指令 逻辑运算指令 与或&#xff0c;异或 左移右移 内存操作 LOAD/STORE 指令 写 读 CPU的栈机制 栈的概念 栈的种类 1.空栈(…

Java生成Excel_低内存占用_更快

EasyExcel&#xff1a;高效Java Excel工具&#xff0c;解决大文件读写难题 EasyExcel是一个基于Java的、快速简洁且能有效解决大文件内存溢出问题的Excel处理工具。它使得用户可以在无需过多关注性能和内存消耗的情况下&#xff0c;轻松实现Excel文件的读写功能。相较于传统的…

无头浏览器测试:如何使用 Puppeteer 和 Browserless?

什么是无头浏览器测试&#xff1f; 无头浏览器测试通常指没有头的物体或东西&#xff0c;在浏览器的语境中&#xff0c;它指的是没有 UI 的浏览器模拟。无头浏览器自动化使用 Web 浏览器进行端到端测试&#xff0c;而无需加载浏览器的 UI。 无头模式是一个功能&#xff0c;它…

Canvas:AI协作的新维度

在人工智能的浪潮中&#xff0c;OpenAI的最新力作Canvas&#xff0c;不仅是一款新工具&#xff0c;它标志着人工智能协作方式的一次革命性飞跃。Canvas为写作和编程提供了一个全新的交互界面&#xff0c;让用户能够与ChatGPT进行更紧密、更直观的协作。 ​​​​​​​ Canvas的…

Android targetSdkVersion 升级为34 问题处理

原因是发布到GooglePlay遭到拒绝&#xff0c;需要最低API level为34。之前为31&#xff0c;感觉还挺高的&#xff0c;但是GooglePlay需要的更高。 记录下处理问题&#xff1a; 1.升级gradle版本为8.0.2 之前是&#xff1a; classpath com.android.tools.build:gradle:7.1.0-…

sql注入第8关

手工注入麻烦 目录 判断闭合方式 判断注入类型 手工注入 1、获取数据库名 2、爆破数据库的名字&#xff08;security&#xff09; 3、爆破表的数量 4、判断表名的长度 5、判断表的列名数量 6、判断表的列名的名字 7、获取表的数据 8、判断数据的长度 9、判断数据的…

Golang | Leetcode Golang题解之第464题我能赢吗

题目&#xff1a; 题解&#xff1a; func canIWin(maxChoosableInteger, desiredTotal int) bool {if (1maxChoosableInteger)*maxChoosableInteger/2 < desiredTotal {return false}dp : make([]int8, 1<<maxChoosableInteger)for i : range dp {dp[i] -1}var dfs …

点云深度学习模型PointNet

随着3D传感器&#xff08;如激光雷达、深度相机&#xff09;的广泛应用&#xff0c;点云数据已成为计算机视觉和机器人领域的重要数据形式。点云是一组在三维空间中具有 (x, y, z) 坐标的离散点的集合&#xff0c;用于表示物体的形状或场景。然而&#xff0c;由于点云的无序性、…

pycharm生成的exe执行后报错

元素 application 显示为元素 urn:schemas-microsoft-com:asm.v1^dependentAssembly (此版本的 Windows 不支持)的子元素。 日志名称: Application 来源: SideBySide 日期: 2024/10/8 14:14:12 事件 ID: 72 任务类别: 无 级别…

docker升级mysql

一、首选备份原数据库所有数据 二、在Docker中查看正在运行的MySQL容器名称&#xff0c;可以使用以下命令&#xff1a; docker ps --filter "namemysql" 三、查看当前docker中正在运行mysql的版本 docker exec -it qgz-mysql mysql -V 可以看到当前运行的版本是8.…

[C++]使用纯opencv部署yolov8-cls图像分类onnx模型

【算法介绍】 使用纯OpenCV部署YOLOv8-cls图像分类ONNX模型涉及几个关键步骤。 首先&#xff0c;你需要将YOLOv8-cls模型从PyTorch格式转换为ONNX格式&#xff0c;这是为了确保模型在不同深度学习框架之间的互操作性。这个转换过程通常是通过ultralytics框架中的model.export…

大数据-158 Apache Kylin 安装配置详解 集群模式启动

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

C++刷怪笼(7)string类

目录 1.前言 2.正文 2.1标准库中的string类 2.1.1string类 2.1.2auto和范围for 2.1.3string类的常用接口说明 2.2string类的模拟实现 2.2.1经典的string类问题 2.2.2浅拷贝 2.2.3深拷贝 ​编辑 2.2.4写时拷贝 3.小结 1.前言 前面我们对C的封装这一大特性进行了详细…

【Flutter、H5、Web?前端个人总结】分享从业经历经验、自我规范准则,纯干货

前言 hi&#xff0c;正式接触web前端已经经过了两年的时间&#xff0c;从大学的java后端转型到web前端&#xff0c;再到后续转战Flutter&#xff0c;逐渐对前端有了一些心得体会&#xff0c;其实在当下前端的呈现形式一直在变化&#xff0c;无论你是用原生、还是web还是混编的…

吸毛效果好的宠物空气净化器分享,希喂、霍尼韦尔、米家实测

说起宠物空气净化器&#xff0c;几年前我可能会一脸鄙夷&#xff1a;为啥要花这种智商税冤枉钱&#xff1f; 直到之前养了一只猫&#xff0c;被家中乱飞的浮毛和滂臭的异味搞到头晕&#xff0c;于是作为i一个养宠的家电测评博主&#xff0c;索性对宠物空气净化器这玩意做了超级…

如何在银河麒麟服务器中获取关键日志信息

如何在银河麒麟服务器中获取关键日志信息 1、获取messages日志2、获取dmesg输出 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在银河麒麟服务器中&#xff0c;获取messages和dmesg日志是排查问题的重要步骤。 1、dmesg命令用于显示或控制…