当前位置: 首页 > article >正文

Qt常用控件——QLCDNumber

文章目录

    • QLCDNumber核心属性
    • 倒计时小程序
    • 倒计时小程序相关问题

QLCDNumber核心属性

QLCDNumber是专门用来显示数字的控件,类似于这样:

image-20240911213827270

属性说明
intValue获取的数字值(int).
value获取的数字值(double)
和intValue是联动的
例如value设为1.5,intValue值就是2
设置value和intValue的方法名为display
digitCount显示几位数字
mode数字显示形式:
QLCDNumber::Dec:显示十进制(只有十进制才能显示小数点后的内容)
QLCDNumber::Hex:显示十六进制
QLCDNumber::Bin:显示二进制
QLCDNumber::Oct:显示八进制
segmentStyle设置显示风格:
QLCDNumber::Flat:平面显示风格,数字呈现在平坦的表面
QLCDNumber::Outline:轮廓风格显示,数字有清晰的轮廓和阴影效果
QLCDNumber::Filled:填充显示风格,数字被填充颜色与背景区分
smallDecimalPoint设置较小的小数点

倒计时小程序

使用QLCDNumber显示一个初始值,每隔一秒数字减一,一直到0

不同显示风格:

image-20240911220401764

设置起始10秒:

ui->lcdNumber->display("10");

接下来的关键就是“每秒钟-1”这个效果。

这个属于——周期性执行某个逻辑,这类组件叫做“定时器”。

在C++标准库并没有提供定时器实现,Boost里面实现了。

另外Qt里面也封装了对应的计算器,而且封装了信号槽机制:

QTimer类:

通过这个类创建出的对象,就会产生一个timeout这样的信号,可以通过start方法来开启定时器,并且设定参数触发timeout信号的周期。

然后这样就可以结合connect把这个timeout信号绑定到需要的槽函数当中,就可以修改执行逻辑,修改LCDNumber中的数字了

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 *timer;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QTimer>
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    ui->lcdNumber->display("10");

    //创建QTimer实例
    timer = new QTimer(this);
    //QTimer的timeout信号和槽函数链接
    connect(timer, &QTimer::timeout, this, &Widget::handle);
    //启动计时器 参数为触发周期 单位是 ms
    timer->start(1000);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::handle()
{
    //获取lcdNumber数字
    int val = ui->lcdNumber->intValue();
    if(val <= 0)
    {
        timer->stop();
        return;
    }
    ui->lcdNumber->display(val - 1);
}

GIF 2024-9-11 22-20-05


倒计时小程序相关问题

上面是借助QTimer完成的倒计时功能,也可以使用while循环,每一秒减一来实现

Tips:

Windows提供了Sleep的接口,只能在Visual Studio里面使用;

而目前Qt采用的是mingw,windows版本的gcc,是无法使用Sleep的;

C++11标准库引入了sleep操作:sleep_for

#include "widget.h"
#include "ui_widget.h"
#include<thread>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    int val = ui->lcdNumber->intValue();
    while(true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        if(val <= 0)
        {
            break;
        }
        ui->lcdNumber->display(--val);
    }
}

Widget::~Widget()
{
    delete ui;
}

运行程序之后发现,并没有显示窗口,而是运行完毕之后,才显示计算完毕的窗口:

GIF 2024-9-11 22-33-38

这是因为这段逻辑,都是在构造函数当中完成的,构造完毕之后,才会显示

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

如果构造函数当中创建一个线程,然线程去执行这段逻辑,是否可以?

#include "widget.h"
#include "ui_widget.h"
#include<thread>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

//    int val = ui->lcdNumber->intValue();
//    while(true)
//    {
//        std::this_thread::sleep_for(std::chrono::seconds(1));
//        if(val <= 0)
//        {
//            break;
//        }
//        ui->lcdNumber->display(--val);
//    }
    std::thread t([this](){
        int val = this->ui->lcdNumber->intValue();
        while(true)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            if(val <= 0)
            {
                break;
            }
            ui->lcdNumber->display(--val);
        }
    });
}

Widget::~Widget()
{
    delete ui;
}

运行程序之后,报错了:

image-20240911223931200

这是因为Qt里面,界面有一个专门的线程去负责维护更新的(主线程,main函数所在线程)

对于GUI来说,内部包含了很多隐藏状态,Qt为了保证修改界面的工程中,线程安全不会受到影响,Qt禁止了其他线程直接修改界面。

上面的操作就是修改界面的操作。

因此Qt为了保证线程的按照,直接要求所有对界面的修改操作,必须在主线程当中完成。

对于Qt的槽函数来说,默认情况下,槽函数都是由主线程调用的,在槽函数当中修改界面没有任何问题。

主线程当中,有一个事件循环,在main函数当中:

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();	//事件循环
}

a.exec会使主线程进入事件循环,每执行一次循环,就会有固定的事情要做

综上所述,使用定时器实现倒计时,是较为合理的方案,后续如果有周期性修改界面状态的操作,优先考虑定时器


http://www.kler.cn/news/309761.html

相关文章:

  • scantf
  • Linux--守护进程与会话
  • Java 中 List 常用类和数据结构详解及案例示范
  • 基于python+django+vue的外卖管理系统
  • java循环遍历树状结构对象并转换成另外树状结构对象
  • 6.安卓逆向-安卓开发基础adb工具
  • 学习贵在善假于物
  • 什么是科技与艺术相结合的异形创意圆形(饼/盘)LED显示屏
  • YooAsset基础操作及热更
  • 自监督的主要学习方法
  • Web植物管理系统-下位机部分
  • Facebook主页,广告账户,BM被封分别怎么解决?
  • sicp每日一题[2.17]
  • Ubuntu上如何使用sh文件更新CMake
  • 【二十一】【QT开发应用】ListWiddget图标模式
  • yolo自动化项目实例解析(二)ui页面整理
  • 组件上的v-model(数据传递),props验证,自定义事件,计算属性
  • 家电制造的隐形守护者:矫平机确保材料完美无瑕
  • Linux 调用write()函数后,内核一般多久将数据写入磁盘
  • Java轻量级测试框架的实现与使用 总篇
  • 【资料分析】刷题日记1
  • 保护您的企业免受网络犯罪分子侵害的四个技巧
  • 【运维监控】Prometheus+grafana监控flink运行情况
  • SpringBoot2:web开发常用功能实现及原理解析-@ControllerAdvice实现全局异常统一处理
  • [苍穹外卖]-10WebSocket入门与实战
  • SpringBoot整合WebSocket实现消息推送或聊天功能示例
  • 从头开始学MyBatis—02基于xml和注解分别实现的增删改查
  • (java+Seleniums3)自动化测试实战2
  • ssh远程连接try1账号切换tips
  • 宝兰德MCP系列介绍 ①:中间件管理能力全线升级,驱动企业数字化管理效能提升