【Qt入门系列】一文掌握 Qt 常用显示类控件:QLCDNumber、QProgressBar 与 QCalendarWidget

🔥 本文专栏:Qt

🌸作者主页:努力努力再努力wz

💪 今日博客励志语录别怕慢,怕的是你一边走一边怀疑这条路,结果连慢都没攒下来。


思维导图

引入

在此前的学习中,我们已经了解了 Qt 中的一些常用控件,包括按钮类控件和标签类控件。通过这些内容,我们初步认识了 Qt 控件的基本使用方式,以及控件在界面显示、用户交互和信号槽机制中的作用。

本文将继续围绕 Qt 常用控件展开,进一步学习其他典型控件的使用方式,并结合实际代码分析其常见属性、信号槽连接方式以及在界面开发中的应用场景。

QLCDNumber 数字显示控件:从基础显示控制到倒计时案例

QLCDNumber:LCD 数字显示控件的基本使用与显示控制

首先要介绍的显示类控件是 QLCDNumberLCD 数字显示控件 。从功能定位上来看,QLCDNumber 和前面学习过的 QLabel 有一定相似之处,它们都可以在界面中展示内容。不过二者的侧重点并不相同:QLabel 更偏向通用文本或图片展示,可以显示普通字符串、富文本以及图片;而 QLCDNumber 则更侧重于数值展示,它会以类似电子表、计算器或数码管的 LCD 风格显示数字。

在实际开发中,QLCDNumber 的外观属性既可以在 Qt Designer 中通过可视化方式进行设置,也可以通过 C++ 代码进行控制。例如,可以设置它的数字位数、显示模式、小数点样式等属性。

对于 QLCDNumber 来说,设置当前显示内容的核心接口是 display()。该接口提供了多个重载版本,既可以接收整数,也可以接收浮点数,还可以接收字符串形式的内容,并将其以 LCD 数字风格显示到界面中。

cpp 复制代码
ui->lcdNumber->display(10);       // 显示整数
ui->lcdNumber->display(3.14);     // 显示浮点数
ui->lcdNumber->display("12:30");  // 显示部分 LCD 风格支持的字符串

需要注意的是,虽然 display() 可以接收字符串参数,但 QLCDNumber 并不是通用字符串显示控件。由于它采用 LCD 数码管风格进行绘制,因此只能显示数字以及少量适合数码管表示的字符,例如负号、小数点、冒号、部分英文字母等。如果传入了不支持的字符,这些字符会被替换为空格。

因此,如果只是普通文本展示,更适合使用 QLabel;如果是数字、时间、计数器、倒计时等内容展示,则更适合使用 QLCDNumber

除了设置显示值之外,QLCDNumber 还可以控制数值的显示进制。它支持十进制、十六进制、八进制和二进制显示模式:

cpp 复制代码
ui->lcdNumber->setMode(QLCDNumber::Dec); // 十进制
ui->lcdNumber->setMode(QLCDNumber::Hex); // 十六进制
ui->lcdNumber->setMode(QLCDNumber::Oct); // 八进制
ui->lcdNumber->setMode(QLCDNumber::Bin); // 二进制

也可以使用对应的槽函数来切换显示模式:

cpp 复制代码
ui->lcdNumber->setDecMode();
ui->lcdNumber->setHexMode();
ui->lcdNumber->setOctMode();
ui->lcdNumber->setBinMode();

需要注意的是,QLCDNumber 虽然可以通过 display(double) 接收浮点数,但只有在十进制模式下才会正常显示小数部分。当控件处于十六进制、八进制或二进制模式时,传入浮点数本身不会导致接口调用错误,但控件会按照该数值对应的整数形式进行进制显示,因此不会展示小数部分。

对于显示位数,QLCDNumber 提供了 setDigitCount() 接口。该接口用于设置控件当前能够显示的数字位数,例如:

cpp 复制代码
ui->lcdNumber->setDigitCount(5);

这里的 5 表示控件最多显示 5 个数字位,而不是表示小数点后保留 5 位。如果传入 display() 的内容超出了当前 digitCount 所能容纳的范围,控件就无法完整显示该内容,并可能触发 overflow() 信号。

例如:

cpp 复制代码
ui->lcdNumber->setDigitCount(5);
ui->lcdNumber->display(12345);  // 可以完整显示

ui->lcdNumber->display(123456); // 超出 5 位,可能触发 overflow()

如果显示的是小数,还需要结合 setSmallDecimalPoint() 来理解。该接口用于控制小数点的显示方式:

cpp 复制代码
ui->lcdNumber->setSmallDecimalPoint(true);

当参数为 true 时,小数点会以较小的形式显示在数字之间,此时小数点不单独占用一个数字位;当参数为 false 时,小数点会按照正常大小显示,并且会占用一个数字位。

例如,当显示 12.34 时,如果小数点占用一个显示位,那么整体显示结构可以理解为:

text 复制代码
1 2 . 3 4

此时一共需要 5 个显示位置。

cpp 复制代码
ui->lcdNumber->setDigitCount(5);
ui->lcdNumber->setSmallDecimalPoint(false);
ui->lcdNumber->display(12.34);

如果将 digitCount 设置为 4,并且小数点仍然占用一个显示位:

cpp 复制代码
ui->lcdNumber->setDigitCount(4);
ui->lcdNumber->setSmallDecimalPoint(false);
ui->lcdNumber->display(12.34);

此时显示容量就不够了,因为 12.34 需要 1、2、.、3、4 共 5 个显示位置。

而如果启用较小的小数点显示模式:

cpp 复制代码
ui->lcdNumber->setSmallDecimalPoint(true);

小数点就不会单独占用 digitCount 中的一个位置,主要占用显示位的是 1、2、3、4 这几个数字。

因此,QLCDNumber 中几个常用接口之间的关系可以这样理解:display() 用于设置当前显示的值;setMode() 用于控制数值按照什么进制显示;setDigitCount() 用于控制控件整体能够显示多少个数字位;setSmallDecimalPoint() 则用于控制小数点是否单独占用一个显示位。


除了通过 display() 设置当前显示内容之外,QLCDNumber 也提供了用于获取当前显示值的接口。常用的读取接口主要有两个:intValue()value()

其中,intValue() 用于获取当前显示值对应的整数形式,返回值类型为 int;而 value() 用于获取当前显示值对应的浮点形式,返回值类型为 double

cpp 复制代码
ui->lcdNumber->display(3.14);

int n = ui->lcdNumber->intValue();  // 获取整数形式的显示值
double d = ui->lcdNumber->value();  // 获取浮点形式的显示值

需要注意的是,虽然 display() 可以接收浮点数,但如果后续通过 intValue() 获取当前显示值,那么得到的是整数形式,并不会保留小数部分。因此,如果当前控件用于显示计数器、倒计时等整数场景,可以使用 intValue() 获取当前值;如果控件用于显示小数,并且希望保留小数部分,则应该使用 value() 接口。

因此,display() 可以理解为负责"写入当前显示值",而 intValue()value() 则负责"读取当前显示值"。其中,intValue() 侧重整数读取,value() 侧重浮点数读取。

QLCDNumber 实战:结合 QTimer 实现倒计时效果

在认识了 QLCDNumber 的相关属性和常用接口之后,接下来我们通过一个常见的应用场景来进一步理解它的使用方式,这个应用场景就是倒计时。

倒计时的核心逻辑并不复杂:首先在界面中显示一个初始数值,然后每隔一段固定时间对该数值进行更新,直到数值减小到 0 为止。因此,这里除了需要使用 QLCDNumber 显示当前倒计时数值之外,还需要借助 QTimer 类来完成周期性触发任务。

QTimer 本质上是 Qt 提供的定时器类,它可以按照指定的时间间隔周期性地发出 timeout() 信号。我们只需要将该信号和自定义槽函数进行连接,就可以在槽函数中完成周期性任务,例如更新 QLCDNumber 当前显示的数值。

需要注意的是,QTimer 并不是显示类控件,它不会直接显示在界面中。前面学习 QLabelQPushButton 等控件时,给控件传递父指针通常有两层含义:一方面是应用 Qt 的父子对象机制,让子对象的生命周期交给父对象管理;另一方面是确定该控件显示在哪个父窗口区域中。

但是对于 QTimer 来说,它并不继承 QWidget,而是继承自 QObject,因此它不具备界面显示能力。创建 QTimer 对象时传入 this,主要是为了应用 Qt 的对象树机制:

cpp 复制代码
timer = new QTimer(this);

这样一来,timer 就会成为当前 Widget 对象的子对象。当 Widget 被销毁时,作为子对象的 QTimer 也会被自动销毁,从而避免我们手动释放定时器对象。

创建定时器对象之后,可以通过 start() 设置定时器的触发间隔。start() 接收的参数单位是毫秒,例如:

cpp 复制代码
timer->start(1000);

表示定时器每隔 1000ms,也就是每隔 1 秒发出一次 timeout() 信号。接着通过 connect()timeout() 信号和槽函数绑定起来:

cpp 复制代码
connect(timer, &QTimer::timeout, this, &Widget::handler);

这样每当定时器触发时,都会自动调用 handler() 槽函数。在槽函数中,我们可以先通过 intValue() 获取 QLCDNumber 当前显示的整数值,然后判断倒计时是否已经结束。如果当前值已经小于等于 0,就调用 stop() 停止定时器;否则将当前值减 1,并再次通过 display() 更新到界面中。

完整代码如下:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QTimer>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 设置 LCD 初始显示值
    ui->lcdNumber->display(10);

    // 创建定时器对象,并将当前窗口作为父对象
    timer = new QTimer(this);

    // 绑定 timeout 信号和自定义槽函数
    connect(timer, &QTimer::timeout, this, &Widget::handler);

    // 每隔 1000ms 触发一次 timeout 信号
    timer->start(1000);

    // 设置 LCD 控件样式
    ui->lcdNumber->setStyleSheet(
        "QLCDNumber {"
        "color: green;"
        "background-color: black;"
        "border: 2px solid gray;"
        "}"
    );
}

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

void Widget::handler()
{
    int value = ui->lcdNumber->intValue();

    if (value <= 0)
    {
        timer->stop();
        return;
    }

    value--;
    ui->lcdNumber->display(value);
}

在这个案例中,QLCDNumber 负责显示当前倒计时数值,而 QTimer 负责按照固定时间间隔触发更新逻辑。二者结合之后,就可以实现一个简单的倒计时效果。

QProgressBar 进度条控件:范围设置、进度更新与定时器模拟

根据上文,我们已经认识了 QLCDNumber 这种 LCD 数字显示控件。接下来要学习的显示类控件是 QProgressBar,也就是进度条控件。

QProgressBar 主要用于在界面中展示某个任务的完成进度。它会根据当前值在指定区间中的位置,计算出当前进度比例,并以进度条长度的形式展示出来。简单来说,进度条的显示效果取决于三个核心值:最小值、最大值以及当前值。

其中,最小值和最大值用于确定整个进度范围,当前值用于表示任务当前执行到了哪个位置。进度比例可以简单理解为:

text 复制代码
当前进度比例 = (当前值 - 最小值) / (最大值 - 最小值)

因此,当我们将进度条范围设置为 0 ~ 100 时,当前值就可以直接理解为百分比。例如,当前值为 30,就表示任务完成了 30%;当前值为 100,就表示任务已经完成。

在代码中,可以通过 setMinimum()setMaximum() 分别设置进度条的最小值和最大值:

cpp 复制代码
ui->progressBar->setMinimum(0);
ui->progressBar->setMaximum(100);

也可以使用 setRange() 一次性设置进度条的范围:

cpp 复制代码
ui->progressBar->setRange(0, 100);

设置好范围之后,可以通过 setValue() 设置当前进度值:

cpp 复制代码
ui->progressBar->setValue(0);

而如果需要获取当前进度条的值,则可以调用 value() 接口:

cpp 复制代码
int value = ui->progressBar->value();

需要注意的是,QProgressBar 的当前值是整数类型,因此它通常适合用来表示整数进度。例如,在 0 ~ 100 的范围中,可以将当前值直接理解为百分比;而在文件读取、文件下载、文件传输等场景中,也可以将进度条范围设置为 0 ~ 文件总大小,再根据当前已经读取或传输的字节数更新进度条。

例如,在文件读取场景中,可以先获取文件总大小,然后将进度条的最大值设置为文件总字节数。随着文件不断被读取,再将已经读取的字节数设置为当前值,这样进度条就可以根据真实读取进度进行变化。

为了演示 QProgressBar 的基本使用方式,我们可以先实现一个简单的模拟进度条案例。这里仍然需要借助 QTimer 定时器类。QTimer 会按照指定时间间隔周期性地发出 timeout() 信号,我们将该信号和槽函数绑定起来,然后在槽函数中不断修改进度条的当前值,就可以模拟一个自动增长的进度条效果。

完整代码如下:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QTimer>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 设置进度条范围
    ui->progressBar->setRange(0, 100);

    // 设置进度条初始值
    ui->progressBar->setValue(0);

    // 创建定时器对象,并将当前窗口作为父对象
    qtimer = new QTimer(this);

    // 绑定 timeout 信号和自定义槽函数
    connect(qtimer, &QTimer::timeout, this, &Widget::handler);

    // 每隔 10ms 触发一次 timeout 信号
    qtimer->start(10);
}

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

void Widget::handler()
{
    int value = ui->progressBar->value();

    if (value >= 100)
    {
        qtimer->stop();
        return;
    }

    value++;
    ui->progressBar->setValue(value);
}

在这段代码中,首先将进度条的范围设置为 0 ~ 100,并将初始值设置为 0。随后创建一个 QTimer 定时器对象,并将它的 timeout() 信号连接到 handler() 槽函数。

当定时器启动后,它会每隔 10ms 触发一次 timeout() 信号,从而调用一次 handler()。在槽函数中,我们先通过 value() 获取进度条当前的值,如果当前值已经大于等于 100,说明进度条已经到达最大值,此时调用 stop() 停止定时器;否则将当前值加 1,再通过 setValue() 更新进度条显示。

通过这个案例可以看到,QProgressBar 负责展示当前进度,而 QTimer 负责周期性触发更新逻辑。二者结合之后,就可以实现一个自动增长的进度条效果。

QCalendarWidget 日历控件:显示属性、日期范围与选择事件

认识了进度条控件之后,接下来我们继续学习另一个常用的显示类控件:QCalendarWidget,也就是日历控件。

和前面学习的 QLCDNumberQProgressBar 相比,QCalendarWidget 展示的内容结构要更加复杂。QLCDNumber 主要用于展示数字,QProgressBar 主要用于展示进度比例,而 QCalendarWidget 则会在界面中绘制出一个接近我们日常使用习惯的日历,用于展示日期信息,并支持用户选择具体日期。

从界面结构上来看,QCalendarWidget 通常由上方的导航区域和下方的日期表格组成。上方导航区域用于显示当前年份和月份,并提供月份切换功能;下方日期表格则按照周和日期进行组织,每一个单元格都对应一个具体日期。用户可以通过鼠标点击的方式在日历中选择日期。

对于 QCalendarWidget 来说,Qt 也提供了一系列接口用于控制日历的显示效果。首先,可以通过 setGridVisible() 设置日历表格是否显示网格线:

cpp 复制代码
ui->calendarWidget->setGridVisible(true);

当参数为 true 时,日历中的日期单元格之间会显示网格线;当参数为 false 时,则不会显示网格线。

不显示网格线:

显示网格线:

其次,可以通过 setHorizontalHeaderFormat() 设置日历控件横向表头的显示格式。这里的横向表头,指的是日历日期区域上方用于显示星期名称的一行。例如,在日历表格中,日期区域上方通常会显示"星期一、星期二、星期三......"或者对应的缩写形式,这一行就是横向表头。

cpp 复制代码
ui->calendarWidget->setHorizontalHeaderFormat(QCalendarWidget::ShortDayNames);

QCalendarWidget::ShortDayNames 表示使用较短的星期名称进行显示。例如在英文环境下,完整星期名称可能是 MondayTuesdayWednesday,而较短名称则可能显示为 MonTueWed。也就是说,ShortDayNames 会使用星期名称的缩写形式,避免表头内容过长。

除了 ShortDayNames 之外,QCalendarWidget 还提供了其他几种横向表头显示方式:

cpp 复制代码
ui->calendarWidget->setHorizontalHeaderFormat(QCalendarWidget::LongDayNames);
ui->calendarWidget->setHorizontalHeaderFormat(QCalendarWidget::ShortDayNames);
ui->calendarWidget->setHorizontalHeaderFormat(QCalendarWidget::SingleLetterDayNames);
ui->calendarWidget->setHorizontalHeaderFormat(QCalendarWidget::NoHorizontalHeader);

其中,LongDayNames 表示显示完整的星期名称,例如 MondayShortDayNames 表示显示较短的星期缩写,例如 MonSingleLetterDayNames 表示只显示单字母形式,例如 M;而 NoHorizontalHeader 则表示隐藏横向星期表头。

如果处于中文环境下,实际显示内容可能会受到系统语言环境和 Qt 本地化配置的影响。例如,完整名称可能显示为"星期一",较短名称可能显示为"周一"或者"一"。因此,在理解这个接口时,不需要死记具体显示成什么文字,只需要抓住它的核心作用:setHorizontalHeaderFormat() 用于控制日历上方"星期表头"的显示形式。

除了横向表头之外,QCalendarWidget 还可以通过 setVerticalHeaderFormat() 设置纵向表头的显示格式。

这里需要注意,纵向表头并不是日历顶部显示年份和月份的区域。顶部显示当前年份、月份,并且可以切换上一个月或下一个月的区域,更准确地说应该叫导航栏或导航区域。而纵向表头指的是日历日期表格最左侧的一列。

横向表头通常位于日期表格上方,用于显示一周中的星期名称,例如"周一、周二、周三......";而纵向表头则位于日期表格左侧,通常用于显示当前这一行日期属于一年中的第几周。

例如,当设置为:

cpp 复制代码
ui->calendarWidget->setVerticalHeaderFormat(QCalendarWidget::ISOWeekNumbers);

此时日历表格最左侧会显示一列数字,例如 222324 等。这些数字表示对应这一行日期属于当前年份中的第几周,也就是周编号。

可以简单理解为:

text 复制代码
        周一  周二  周三  周四  周五  周六  周日
22       1    2    3    4    5    6    7
23       8    9   10   11   12   13   14
24      15   16   17   18   19   20   21

其中,左侧的 22 表示这一行日期所在的这一周是当前年份中的第 22 周;下一行的 23 表示下一周是当前年份中的第 23 周。

如果不希望显示这一列周编号,也可以将纵向表头设置为隐藏:

cpp 复制代码
ui->calendarWidget->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);

因此,QCalendarWidget 中几个区域可以这样区分:顶部显示年份和月份的区域是导航栏;日期表格上方显示星期名称的一行是横向表头;日期表格左侧显示周编号的一列是纵向表头。

因此,QCalendarWidget 的基础显示属性可以先从三个方面理解:setGridVisible() 用于控制是否显示日期单元格之间的网格线;setHorizontalHeaderFormat() 用于控制横向星期表头的显示格式;setVerticalHeaderFormat() 用于控制纵向周编号表头的显示格式。

通过这些接口,我们可以对日历控件的基础显示效果进行定制,使其更加符合实际界面需求。


认识了 QCalendarWidget 的显示属性之后,我们还可以继续设置日历控件的可选日期范围。这里所谓的范围并不是普通数值范围,而是日期范围。可以通过 setMinimumDate() 设置最小可选日期,通过 setMaximumDate() 设置最大可选日期:

cpp 复制代码
ui->calendarWidget->setMinimumDate(QDate(2026, 1, 1));
ui->calendarWidget->setMaximumDate(QDate(2026, 12, 31));

也可以使用 setDateRange() 一次性设置最小日期和最大日期:

cpp 复制代码
ui->calendarWidget->setDateRange(QDate(2026, 1, 1), QDate(2026, 12, 31));

需要注意的是,最小日期和最大日期限制的是"用户可以选中的日期范围",而不是简单地控制哪些日期会被绘制出来。由于 QCalendarWidget 通常以完整月份的形式进行展示,为了保证日历表格结构完整,超出范围的日期仍然可能会显示在界面中。

不过,这些超出范围的日期通常会以灰色或禁用状态显示,表示它们不可选中。用户点击这些日期时,日历控件不会将其设置为当前选中日期,因此也不会触发正常的日期选择逻辑。也就是说,日期范围限制影响的是日期的"可选性",而不是一定影响日期是否出现在界面中。

除了设置可选日期范围之外,QCalendarWidget 还提供了日期选择相关的交互机制。当用户在日历中选中的日期发生变化时,控件会发出 selectionChanged() 信号。我们可以将该信号连接到自定义槽函数,然后在槽函数中获取当前选中的日期,并将其显示到标签控件中。

cpp 复制代码
connect(ui->calendarWidget, &QCalendarWidget::selectionChanged,
        this, &Widget::handler);

在槽函数中,可以通过 selectedDate() 获取当前选中的日期。该接口返回的是一个 QDate 类型的对象:

cpp 复制代码
QDate date = ui->calendarWidget->selectedDate();

如果希望将这个日期显示到 QLabel 中,就需要先将 QDate 转换成字符串。这里可以调用 QDatetoString() 接口,并通过格式化字符串控制日期的显示格式:

cpp 复制代码
ui->label->setText(date.toString("yyyy年MM月dd日"));

其中,yyyy 表示四位年份,MM 表示两位月份,dd 表示两位日期。需要注意的是,日期格式化字符串对大小写和重复次数有要求。例如,月份应该使用大写的 MM,日期应该使用小写的 dd。如果格式写错,就可能无法得到预期的显示结果。

当然,toString() 也可以不传递格式化字符串。此时 Qt 会按照默认格式将日期转换成字符串。不过在实际界面开发中,为了让显示效果更加明确,通常会主动指定日期格式。

完整代码如下:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QDate>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 设置日历基础显示属性
    ui->calendarWidget->setGridVisible(true);
    ui->calendarWidget->setHorizontalHeaderFormat(QCalendarWidget::ShortDayNames);
    ui->calendarWidget->setVerticalHeaderFormat(QCalendarWidget::ISOWeekNumbers);

    // 设置日期可选范围
    ui->calendarWidget->setMinimumDate(QDate(2026, 1, 1));
    ui->calendarWidget->setMaximumDate(QDate(2026, 12, 31));

    // 初始化标签内容,默认显示当前系统日期
    ui->label->setText(QDate::currentDate().toString("yyyy年MM月dd日"));

    // 当选中日期发生变化时,更新标签内容
    connect(ui->calendarWidget, &QCalendarWidget::selectionChanged,
            this, &Widget::handler);
}

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

void Widget::handler()
{
    QDate date = ui->calendarWidget->selectedDate();
    ui->label->setText(date.toString("yyyy年MM月dd日"));
}

在这段代码中,QDate::currentDate() 用于获取系统当前日期,并在程序启动时初始化标签内容;而 selectedDate() 用于获取用户在日历控件中当前选中的日期。每当用户选择的日期发生变化时,selectionChanged() 信号都会触发槽函数,从而更新标签中显示的日期信息。

结语

那么这就是本篇文章的全部内容,我会持续更新,希望你能够多多关注,如果本文有帮助到你的话,还请三连加关注,你的支持就是我创作的最大动力!

相关推荐
查拉图斯特拉面条1 小时前
Git操作指南:克隆、提交、推送与避坑大全
大数据·git·elasticsearch
KaiwuDB1 小时前
KaiwuDB 开源校园行扬州大学站 | 点亮开源成长之路
数据库·开源
右耳朵猫AI1 小时前
JS/TS周刊2026W21 | Deno2.8RC、Angular22RC、TypeORM1.0
开发语言·javascript·ecmascript
闪电悠米1 小时前
黑马点评-秒杀优化-02_lua_precheck
开发语言·redis·分布式·缓存·junit·wpf·lua
盈建云系统1 小时前
外贸网站SEO怎么做?从产品关键词到询盘页面,独立站内容优化流程和费用参考
开发语言·网站搭建
玫幽倩1 小时前
2026盘古石取证决赛(APK取证)
数据库·python·电子取证·aes·隐藏·笔记软件·手机取证
Dream_ksw1 小时前
Python多继承之super()继承问题解决
开发语言·python
C++ 老炮儿的技术栈2 小时前
如何利用 OpenCV 将图像显示在对话框窗口上
c语言·c++·人工智能·qt·opencv·计算机视觉·github
迈巴赫车主2 小时前
蓝桥杯21241灯塔java
java·开发语言·数据结构·算法·职场和发展·蓝桥杯·动态规划