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

news2024/11/28 14:48:17

显示类控件

  • 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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    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.coloradmin.cn/o/2189450.html

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

相关文章

Linux安装AnythingLLM

1. AnythingLLM 简介 AnythingLLM 是 Mintplex Labs 开发的一款可以与任何内容聊天的私人ChatGPT&#xff0c;是高效、可定制、开源的企业级文档聊天机器人解决方案。它能够将任何文档、资源或内容片段转化为大语言模型&#xff08;LLM&#xff09;在聊天中可以利用的相…

【Android】设备操作

本文介绍App开发常用的一些设备操作&#xff0c;主要包括如何使用摄像头进行拍照、如何使用麦克风进行录音并结合摄像头进行录像、如何播放录制好的音频和视频、如何使用常见传感器实现业务功能、如何使用定位功能获取位置信息、如何利用短距离通信技术实现物联网等。 摄像头 …

Armeria gPRC 高级特性 - 装饰器、无框架请求、阻塞处理器、Nacos集成、负载均衡、rpc异常处理、文档服务......

文章目录 定义一个示例高级特性装饰器概述简单案例多种装饰方式 无框架请求概述使用方式 阻塞任务处理器背景概述多种使用方式 rpc 异常统一处理使用方式更详细的异常信息 Armeria 提供 gRPC 客户端多种调用方式同步调用异步调用使用装饰器 负载均衡简单案例Armeria 提供的所有…

5G NR相关笔记

为了提供一致且准确的时序定义&#xff0c;NR规范了一个 基本时间单位 T c 1 / ( 480000 4096 ) , T_c1/(480 000\times 4096), Tc​1/(4800004096),所有与5GNR相关的时间的定义都被描述为这个基本时间单位的整数倍。基本时间单位 T c T_c Tc​ 因此可以看成是子载波间隔480…

10.2 Linux_进程_进程相关函数

创建子进程 函数声明如下&#xff1a; pid_t fork(void); 返回值&#xff1a;失败返回-1&#xff0c;成功返回两次&#xff0c;子进程获得0(系统分配)&#xff0c;父进程获得子进程的pid 注意&#xff1a;fork创建子进程&#xff0c;实际上就是将父进程复制一遍作为子进程&…

【AIGC】2023-ICCV-使用 Transformer 的可扩展扩散模型

2023-ICCV-Scalable Diffusion Models with Transformers 使用 Transformer 的可扩展扩散模型摘要1. 引言2. 相关工作3. 扩散 Transformer3.1 准备工作3.2 扩散 Transformer 设计空间 4. 实验设置5. 实验5.1 最先进的扩散模型5.2 缩放模型与采样计算 6. 结论参考文献 使用 Tran…

Ubuntu24.04远程开机

近来在几台机器上鼓捣linux桌面&#xff0c;顺便研究一下远程唤醒主机。 本篇介绍Ubuntu系统的远程唤醒&#xff0c;Windows系统的唤醒可搜索相关资料。 依赖 有远程唤醒功能的路由器&#xff08;当前一般都带这个功能&#xff09;有线连接主机&#xff08;无线连接有兴趣朋友…

PostgreSQL技术内幕13:PostgreSQL通讯协议

文章目录 0.简介1.PG通讯协议1.1 消息格式1.2 消息交互流程1.2.1 启动流程1.2.2 简单查询流程1.2.3 扩展查询1.2.3.1 pipelining 1.2.4 取消流程1.2.5 结束流程1.2.6 copy流程1.2.7 错误和通知 0.简介 之前文章对于PG的内部模块做了一些介绍&#xff0c;接下来对PG和外部交互的…

GS-SLAM论文阅读笔记-MGSO

前言 MGSO首字母缩略词是直接稀疏里程计(DSO)&#xff0c;我们建立的光度SLAM系统和高斯飞溅(GS)的混合。这应该是第一个前端用DSO的高斯SLAM&#xff0c;不知道这个系统的组合能不能打得过ORB-SLAM3&#xff0c;以及对DSO会做出怎么样的改进以适应高斯地图&#xff0c;接下来…

【有啥问啥】SE(Squeeze-and-Excitation)架构详解

SE&#xff08;Squeeze-and-Excitation&#xff09;架构详解 在深度学习&#xff0c;特别是计算机视觉领域&#xff0c;卷积神经网络&#xff08;CNN&#xff09;的发展日新月异。为了进一步提升CNN的特征提取能力和模型性能&#xff0c;研究者们不断探索新的网络架构和组件。…

向量数据库|第1期|从零开始学习

向量数据库|第1期|从零开始学习 1、向量数据库中的基本概念 1.1 什么是余弦 余弦函数是一种三角函数&#xff0c;在直角三角形中&#xff0c;某个锐角的余弦为&#xff1a;临边与斜边的比值&#xff0c;如下图cosAb/c。引申到任意三角形中&#xff0c;即余弦定理&#xff1a;…

2024年7月大众点评全国酒吧前百名城市分析

在做一些城市分析、学术研究分析、商业选址、商业布局分析等数据分析挖掘时&#xff0c;大众点评的数据参考价值非常大&#xff0c;截至2024年7月&#xff0c;大众点评美食店铺剔除了暂停营业、停止营业后的最新数据情况分析如下。 分析研究的字段维度包括大众点评数字id、字母…

LSM6DSV16X基于MLC智能笔动作识别(3)----MEMS Studio训练数据

LSM6DSV16X基于MLC智能笔动作识别.3--MEMS Studio训练数据 概述视频教学样品申请源码下载硬件准备选择MEMS导入数据配置窗口长度和量程配置滤波器选择特征数据设备树生成决策树生成参考程序转换UCF文件 概述 MEMS-Studio是一套完整的桌面软件解决方案&#xff0c;专为开发嵌入…

认知杂谈98《抵御噪声干扰》

内容摘要&#xff1a; “能量掠夺”是指他人负面言行对我们情绪和心理状态的不良影响&#xff0c;使我们感到沮丧或愤怒。这种影响可能源于我们内心对自身价值认同的不坚定&#xff0c;以及过分在意他人的看法。 要避免能量掠夺&#xff0c;我们需要建立心理防线&#xff0c;学…

Xilinx Vitis IDE启动时失去响应的解决办法

在启动Xilinx Vitis IDE时&#xff0c;有时候会遇到卡死的情况&#xff0c;无论是直接启动还是从Vivado的菜单中启动都一样。参考Xilinx官网的解决办法&#xff1a;&#xff08;一直到2023.1版本都是可以解决的&#xff0c;之后的版本没测过。&#xff09; Widget (amd.com) …

Leetcode—279. 完全平方数【中等】

2024每日刷题&#xff08;169&#xff09; Leetcode—279. 完全平方数 实现代码 class Solution { public:int numSquares(int n) {vector<int> dp(n 1, n);dp[0] 0;dp[1] 1;for(int i 2; i < n; i) {for(int j 1; j * j < i; j) {dp[i] min(dp[i], dp[i -…

Oracle中ADD_MONTHS()函数详解

文章目录 前言一、ADD_MONTHS()的语法二、主要用途三、测试用例总结 前言 在Oracle数据库中&#xff0c;ADD_MONTHS()函数用于在日期中添加指定的月数。 一、ADD_MONTHS()的语法 ADD_MONTHS(date, n) 其中&#xff0c;date是一个日期值&#xff0c;n是一个整数值&#xff0c…

C语言高阶【2】--动态内存管理【2】--柔性数组(这是个全新的知识点,不想了解一下吗?)

本章概述 柔性数组总结C/C中程序内存划分彩蛋时刻&#xff01;&#xff01;&#xff01;&#xff01; 柔性数组 数组这个东西&#xff0c;我想大家应该都不陌生了吧。但是&#xff0c;柔性数组这个东西可能你是第一次听说。 柔性数组概念&#xff1a;在C99之前是没这个东西的…

基于Flux的文生高清图片

Flux模型生成的图片画质极佳&#xff0c;改进修复了手的问题&#xff0c;支持字体生成和排版&#xff0c;训练参数大&#xff0c;风格多样&#xff0c;分辨率弹性好&#xff0c;embedding通用性好&#xff0c;不需要输入负面提示词。 安装ComfyUI ComfyUI下载安装 下载和配置…

计算机网络:计算机网络概述 —— 网络拓扑结构

文章目录 网络拓扑总线型拓扑特点缺陷 星型拓扑特点缺陷 环型拓扑特点缺陷 网状型拓扑优点缺陷 树型拓扑特点缺陷 网络拓扑 网络拓扑指的是计算机网络中节点&#xff08;计算机、交换机、路由器等&#xff09;之间物理或逻辑连接的结构。网络拓扑定义了节点之间的布局、连接方…