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

Qt基础_xiaozuo

1.Qt基础

Qt三大机制:对象树,信号和槽,事件
特殊类的名词:窗口,组件,控件

2.标准IO

#include <QDebug>int main(int argc, char *argv[])
{qDebug() << "字符串:" << QString("Hello") << ";整数:" << 42 << ";浮点数:" << 3.14;qDebug("格式化输出:整数=%d, 字符串=%s", 100, "Qt");return 0;
}

3.窗口搭建基础QApplication

#include <iostream>
#include <QDebug>
#include <QLabel>
#include <QApplication>int main(int argc, char *argv[])
{QApplication app(argc, argv);QLabel *label=new QLabel();label->setText("普通文本");label->show();return app.exec();
}

4.对象树

Qt对象树是Qt框架中用于自动管理对象生命周期和内存的核心机制,基于父子关系构建层级结构。以下从原理、内存管理、使用规范到调试工具进行系统解析:

5.Qt类的继承图

有别班的XMind

别的班拿过来的继承图:

一、对象树的核心原理

1.父子关系构建

1.1树形结构:每个QObject对象可有一个父对象(parent)和多个子对象(children)。子对象通过构造函数或setParent()加入父对象的子对象列表。

1.2自动维护:父对象析构时,递归销毁所有子对象,避免内存泄漏。

1.3动态调整:通过setParent()可动态修改父子关系,对象树结构随程序运行变化。

2.内存管理机制

2.1自动析构:父对象销毁时,其子对象列表中的所有对象被自动delete,无需手动释放。

2.2防二次删除:Qt内部机制确保对象不被重复删除(如子对象销毁后自动从父对象列表中移除)。

2.3栈对象风险:

正确顺序:父对象创建于子对象之前(如QWidget parent; QPushButton child(&parent);)。

错误顺序:若子对象先创建且父对象后析构,会导致子对象被重复删除(崩溃)。

二、对象树的实践规范

1.对象创建与销毁

1.1堆对象优先:通过new创建子对象并指定父对象,生命周期由对象树管理。

1.2避免栈对象:局部变量可能因作用域结束过早析构,破坏对象树完整性。

1.3禁止静态对象:静态对象在main()结束后才析构,可能晚于QApplication销毁,违反Qt对象生命周期规则。

2.父子关系操作

2.1设置父对象:

// 方式1:构造函数指定
QPushButton *btn = new QPushButton(parentWidget);
// 方式2:显式设置
btn->setParent(parentWidget);

2.2解除父子关系:

调用setParent(nullptr)将对象移出对象树,需手动管理内存。

三、常见问题与规避策略

1.内存泄漏场景

未指定父对象的堆对象(需手动delete)。

循环引用(如对象A的父对象是B,B的父对象又是A)导致无法自动释放。

2.崩溃场景

顺序错误:父对象析构早于子对象(如栈对象顺序不当)。

跨线程操作:非GUI线程修改对象树需使用QObject::moveToThread()。

四、调试与工具

1.对象树查看

调试输出:

parentObj->dumpObjectTree();  // 打印对象树结构(Debug模式生效)

动态查询:

qDebug() << childObj->parent();  // 查看父对象
const QObjectList& children = parentObj->children();  // 获取子对象列表

按名称查找:

findChild<T>()和findChildren<T>()支持递归搜索子对象。

总结:最佳实践

1.构造即指定父对象:创建子对象时通过构造函数传入parent参数,避免后续手动设置。

2.统一堆分配:父对象和子对象均通过new创建,由对象树统一管理生命周期。

3.警惕析构顺序:确保父对象生命周期覆盖所有子对象(局部变量严格遵循后创建先析构)。

4.善用调试工具:dumpObjectTree()和findChild系列函数辅助定位对象关系问题。

通过对象树机制,Qt显著简化了C++内存管理,但需严格遵循父子关系规则。深入理解其原理可避免常见陷阱,提升代码健壮性。

=========================================================================

信号与槽机制

信号

以下是 C++ Qt 中信号(Signal)机制的详细解析,结合核心原理、语法规则及实际应用场景:

一、信号的本质与定义

1.信号是什么

事件通知:信号是对象在特定事件(如按钮点击、数据更新)发生时发出的广播式通知。

声明方式:在类声明中使用 signals 关键字,无需实现(由 Qt 的元对象编译器 moc 自动生成)。

class MyClass : public QObject {Q_OBJECT
signals:void dataChanged(int value);  // 声明信号
};

2.信号的触发

通过 emit 关键字触发信号,可携带参数:

void MyClass::updateValue() {int newValue = 10;emit dataChanged(newValue);  // 发射信号
}

二、信号的工作原理

(元对象系统)

1.底层依赖

元对象系统(Meta-Object System):信号槽机制的核心,通过 Q_OBJECT 宏启用。moc 工具在编译时生成 moc_*.cpp 文件,包含信号映射表和动态调用逻辑。

动态查找:信号发出时,Qt 通过 QMetaObject 查找连接的槽函数并执行。

2.连接过程

使用 QObject::connect() 建立信号与槽的绑定:

connect函数所在类: QObject::connect

connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);

三、信号与槽的连接规则

1.参数匹配规则

1.数量兼容:槽函数的参数数量 ≤ 信号参数数量,多余信号参数被忽略。

2.类型与顺序:槽函数参数类型和顺序必须与信号严格一致(如 int 不能匹配 QString)。

示例:

// 信号:void mySignal(int a, float b);
// 合法槽:void slot1(int a); void slot2(int a, float b);
// 非法槽:void slot3(float b);  // 类型不匹配

2.连接类型(第五参数Qt::ConnectionType)

类型行为适用场景
Qt::AutoConnection (默认)同线程→直接调用;跨线程→队列调用通用
Qt::DirectConnection立即在发送者线程调用槽函数单线程实时响应
Qt::QueuedConnection槽函数在接收者线程的事件循环中异步调用跨线程通信(安全)
Qt::BlockingQueuedConnection类似队列连接,但发送者线程阻塞直到槽完成线程间同步
Qt::UniqueConnection避免重复连接(需与上述类型按位或)防止多次绑定

四、高级特性与注意事项

1.信号重载处理

当信号存在重载(如 QComboBox::currentIndexChanged(int) 和 QComboBox::currentIndexChanged(QString)),需明确指定版本:

//通过QOverload<>转换
connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MyClass::onIndexChanged);//通过static_cast<>转喊
connect(comboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MyClass::onIndexChanged);

2.Lambda 表达式作为槽

Qt5 支持 Lambda 替代传统槽函数,简化代码:

connect(button, &QPushButton::clicked, [=]() {qDebug() << "Button clicked!";
});

3.断开连接

使用 disconnect() 手动解除绑定,避免无效调用:

disconnect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);

五、信号槽机制的优势与局限

优势:

松耦合:对象无需相互引用,通过信号通信。
线程安全:`QueuedConnection` 支持跨线程调用。
类型安全:编译时检查参数匹配(Qt5+ 语法)。

局限:

性能开销:动态查找槽函数比直接函数调用慢约 10 倍(通常可接受)。
调试复杂度:间接调用链增加问题定位难度。

最佳实践建议

1.优先使用 Qt5+ 语法:

connect(sender, &Sender::signal, receiver, &Receiver::slot);  // 编译期类型检查

2. 跨线程通信必用 `QueuedConnection`:防止竞态条件。


3. 避免在槽中阻塞:耗时操作应移至子线程。


4. 资源管理:对象销毁前调用 `disconnect()`,或使用 `QPointer` 智能指针。

信号槽机制是 Qt 的核心创新,通过 元对象系统 实现动态绑定,以 解耦设计 和 跨线程安全性 成为 GUI/异步编程的基石。深入理解其规则可高效构建健壮应用。完整文档见 Qt 官方手册。

槽(重复)

以下是关于 C++ Qt 中槽(Slot) 的详细解析,结合核心概念、使用规则及实际应用场景:

一、槽的本质与定义

槽是什么

信号处理器:槽是普通的 C++ 成员函数,用于响应信号(Signal)的触发。

声明方式:在类中使用 slots 关键字声明,支持三种访问权限:

class MyClass : public QObject {Q_OBJECT
public slots:     // 公有槽(任何对象可连接)void publicSlot();
protected slots:  // 保护槽(仅当前类及子类可连接)void protectedSlot();
private slots:   // 私有槽(仅当前类内部可连接)void privateSlot();
};

槽的特性

1.无返回值:必须声明为 void 类型。

2.支持重载:可定义同名但参数不同的槽函数。

3.参数匹配:槽的参数需与信号参数兼容(数量 ≤ 信号参数,类型顺序一致)。

// 信号:void signal(int a, double b);
// 合法槽:void slot(int a);       // 忽略多余参数
// 非法槽:void slot(double b);   // 类型不匹配

二、槽的使用规则

1.连接信号与槽

通过 QObject::connect() 建立绑定,支持编译期类型检查(Qt5+ 语法):

connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);

连接类型(第五参数 Qt::ConnectionType):

类型行为适用场景
Qt::AutoConnection (默认)同线程→直接调用;跨线程→队列调用通用
Qt::DirectConnection同步调用:槽在发送者线程立即执行单线程实时响应
Qt::QueuedConnection异步调用:槽在接收者线程事件循环中执行跨线程通信(安全)
Qt::BlockingQueuedConnection异步调用,但发送者线程阻塞直到槽完成线程间同步
Qt::UniqueConnection避免重复连接(需与其他类型按位或)防止多次绑定

2.断开连接

使用 disconnect() 手动解除绑定,防止悬空调用:

disconnect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);

三、自定义槽的实践

1.实现要求

必须实现函数体:与信号不同,槽需完整实现逻辑。

支持多种形式:槽可以是成员函数、静态函数、全局函数或 Lambda 表达式。

// Lambda 作为槽
connect(button, &QPushButton::clicked, [=]() {qDebug() << "Button clicked via Lambda!";
});

2.线程安全实践

跨线程通信:必须使用 Qt::QueuedConnection,避免直接访问接收者线程资源:

// 对象 worker 在子线程,mainWidget 在主线程
connect(worker, &Worker::resultReady, mainWidget, &MainWidget::handleResult, Qt::QueuedConnection);

四、注意事项

1.资源管理

跨线程通信:必须使用 Qt::QueuedConnection,避免直接访问接收者线程资源:

避免槽中执行阻塞操作,耗时任务应移至 QThread 或线程池。

2.元对象系统依赖

包含槽的类**必须声明 `Q_OBJECT` 宏**,否则 moc 无法生成元代码。
信号/槽参数类型需被 Qt 元类型系统支持(基本类型或 `qRegisterMetaType()` 注册的类型)。

总结

核心定位:槽是 Qt 信号-槽机制的**响应端**,通过松耦合设计实现对象间通信。
灵活扩展:支持重载、多线程安全连接、Lambda 表达式等现代 C++ 特性。
性能权衡:虽比直接函数调用慢约 10 倍,但解耦优势在 GUI/异步场景中更为关键。

通过合理设计槽函数(如限制耗时操作、规范连接类型),可构建高效健壮的 Qt 应用。完整文档见 Qt 官方手册。

QObject::sender()

在 Qt 框架中,QObject::sender() 是一个关键函数,用于在槽函数内部获取触发当前槽的信号发送者对象指针。以下是其核心要点和使用详解:

Qt基础

Qt三大机制:对象树,信号和槽,事件

特殊类的名词:窗口,组件,控件

标准IO

#include <QDebug>int main(int argc, char *argv[])
{qDebug() << "字符串:" << QString("Hello") << ";整数:" << 42 << ";浮点数:" << 3.14;qDebug("格式化输出:整数=%d, 字符串=%s", 100, "Qt");return 0;
}

窗口搭建基础QApplication

#include <iostream>
#include <QDebug>
#include <QLabel>
#include <QApplication>int main(int argc, char *argv[])
{QApplication app(argc, argv);QLabel *label=new QLabel();label->setText("普通文本");label->show();return app.exec();
}

对象树

Qt对象树是Qt框架中用于自动管理对象生命周期和内存的核心机制,基于父子关系构建层级结构。以下从原理、内存管理、使用规范到调试工具进行系统解析:


Qt类的继承图

Qt6.3继承关系.xmind

别的班拿过来的继承图:

Qt复习继承图.jpg


一、对象树的核心原理

  1. 父子关系构建
    • 树形结构:每个QObject对象可有一个父对象(parent)和多个子对象(children)。子对象通过构造函数或setParent()加入父对象的子对象列表。
    • 自动维护:父对象析构时,递归销毁所有子对象,避免内存泄漏。
    • 动态调整:通过setParent()可动态修改父子关系,对象树结构随程序运行变化。
  2. 内存管理机制
    • 自动析构:父对象销毁时,其子对象列表中的所有对象被自动delete,无需手动释放。
    • 防二次删除:Qt内部机制确保对象不被重复删除(如子对象销毁后自动从父对象列表中移除)。
    • 栈对象风险
      • ✅ 正确顺序:父对象创建于子对象之前(如QWidget parent; QPushButton child(&parent);)。
      • ❌ 错误顺序:若子对象先创建且父对象后析构,会导致子对象被重复删除(崩溃)。

二、对象树的实践规范

  1. 对象创建与销毁
    • 堆对象优先:通过new创建子对象并指定父对象,生命周期由对象树管理。
    • 避免栈对象:局部变量可能因作用域结束过早析构,破坏对象树完整性。
    • 禁止静态对象:静态对象在main()结束后才析构,可能晚于QApplication销毁,违反Qt对象生命周期规则。
  2. 父子关系操作
    • 设置父对象

      // 方式1:构造函数指定
      QPushButton *btn = new QPushButton(parentWidget);
      // 方式2:显式设置
      btn->setParent(parentWidget);
      
    • 解除父子关系:调用setParent(nullptr)将对象移出对象树,需手动管理内存。


三、常见问题与规避策略

  1. 内存泄漏场景
    • 未指定父对象的堆对象(需手动delete)。
    • 循环引用(如对象A的父对象是B,B的父对象又是A)导致无法自动释放。
  2. 崩溃场景
    • 顺序错误:父对象析构早于子对象(如栈对象顺序不当)。
    • 跨线程操作:非GUI线程修改对象树需使用QObject::moveToThread()

四、调试与工具

  1. 对象树查看
    • 调试输出

      parentObj->dumpObjectTree();  // 打印对象树结构(Debug模式生效)
      
    • 动态查询

      qDebug() << childObj->parent();  // 查看父对象
      const QObjectList& children = parentObj->children();  // 获取子对象列表
      
    • 按名称查找findChild<T>()findChildren<T>()支持递归搜索子对象。


总结:最佳实践

  1. 构造即指定父对象:创建子对象时通过构造函数传入parent参数,避免后续手动设置。
  2. 统一堆分配:父对象和子对象均通过new创建,由对象树统一管理生命周期。
  3. 警惕析构顺序:确保父对象生命周期覆盖所有子对象(局部变量严格遵循后创建先析构)。
  4. 善用调试工具dumpObjectTree()findChild系列函数辅助定位对象关系问题。

通过对象树机制,Qt显著简化了C++内存管理,但需严格遵循父子关系规则。深入理解其原理可避免常见陷阱,提升代码健壮性。

信号与槽机制

信号

以下是 C++ Qt 中信号(Signal)机制的详细解析,结合核心原理、语法规则及实际应用场景:


一、信号的本质与定义

  1. 信号是什么

    • 事件通知:信号是对象在特定事件(如按钮点击、数据更新)发生时发出的广播式通知。
    • 声明方式:在类声明中使用 signals 关键字,无需实现(由 Qt 的元对象编译器 moc 自动生成)。
    class MyClass : public QObject {Q_OBJECT
    signals:void dataChanged(int value);  // 声明信号
    };
  2. 信号的触发

    • 通过 emit 关键字触发信号,可携带参数:
    void MyClass::updateValue() {int newValue = 10;emit dataChanged(newValue);  // 发射信号
    }

二、信号的工作原理

(元对象系统)

  1. 底层依赖

    • 元对象系统(Meta-Object System):信号槽机制的核心,通过 Q_OBJECT 宏启用。moc 工具在编译时生成 moc_*.cpp 文件,包含信号映射表和动态调用逻辑。
    • 动态查找:信号发出时,Qt 通过 QMetaObject 查找连接的槽函数并执行。
  2. 连接过程

    • 使用 QObject::connect() 建立信号与槽的绑定:

      connect函数所在类: QObject::connect

    connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);
    

三、信号与槽的连接规则

  1. 参数匹配规则

    • 数量兼容:槽函数的参数数量 ≤ 信号参数数量,多余信号参数被忽略。

    • 类型与顺序:槽函数参数类型和顺序必须与信号严格一致(如 int 不能匹配 QString)。

    • 示例

      // 信号:void mySignal(int a, float b);
      // 合法槽:void slot1(int a); void slot2(int a, float b);
      // 非法槽:void slot3(float b);  // 类型不匹配
      
  2. 连接类型(第五参数Qt::ConnectionType

    类型行为适用场景
    Qt::AutoConnection (默认)同线程→直接调用;跨线程→队列调用通用
    Qt::DirectConnection立即在发送者线程调用槽函数单线程实时响应
    Qt::QueuedConnection槽函数在接收者线程的事件循环中异步调用跨线程通信(安全)
    Qt::BlockingQueuedConnection类似队列连接,但发送者线程阻塞直到槽完成线程间同步
    Qt::UniqueConnection避免重复连接(需与上述类型按位或)防止多次绑定

四、高级特性与注意事项

  1. 信号重载处理

    • 当信号存在重载(如 QComboBox::currentIndexChanged(int)QComboBox::currentIndexChanged(QString)),需明确指定版本:
    //通过QOverload<>转换
    connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MyClass::onIndexChanged);//通过static_cast<>转喊
    connect(comboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MyClass::onIndexChanged);
    
  2. Lambda 表达式作为槽

    • Qt5 支持 Lambda 替代传统槽函数,简化代码:
    connect(button, &QPushButton::clicked, [=]() {qDebug() << "Button clicked!";
    });
    
  3. 断开连接

    • 使用 disconnect() 手动解除绑定,避免无效调用:
    disconnect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);
    

五、信号槽机制的优势与局限

  • ✅ 优势
    • 松耦合:对象无需相互引用,通过信号通信。
    • 线程安全QueuedConnection 支持跨线程调用。
    • 类型安全:编译时检查参数匹配(Qt5+ 语法)。
  • ❌ 局限
    • 性能开销:动态查找槽函数比直接函数调用慢约 10 倍(通常可接受)。
    • 调试复杂度:间接调用链增加问题定位难度。

最佳实践建议

  1. 优先使用 Qt5+ 语法

    connect(sender, &Sender::signal, receiver, &Receiver::slot);  // 编译期类型检查
    
  2. 跨线程通信必用 QueuedConnection:防止竞态条件。

  3. 避免在槽中阻塞:耗时操作应移至子线程。

  4. 资源管理:对象销毁前调用 disconnect(),或使用 QPointer 智能指针。

信号槽机制是 Qt 的核心创新,通过 元对象系统 实现动态绑定,以 解耦设计 和 跨线程安全性 成为 GUI/异步编程的基石。深入理解其规则可高效构建健壮应用。完整文档见 Qt 官方手册。

槽(重复)

以下是关于 C++ Qt 中槽(Slot) 的详细解析,结合核心概念、使用规则及实际应用场景:


一、槽的本质与定义

  1. 槽是什么

    • 信号处理器:槽是普通的 C++ 成员函数,用于响应信号(Signal)的触发。

    • 声明方式:在类中使用 slots 关键字声明,支持三种访问权限:

      class MyClass : public QObject {Q_OBJECT
      public slots:     // 公有槽(任何对象可连接)void publicSlot();
      protected slots:  // 保护槽(仅当前类及子类可连接)void protectedSlot();
      private slots:   // 私有槽(仅当前类内部可连接)void privateSlot();
      };
  2. 槽的特性

    • 无返回值:必须声明为 void 类型。

    • 支持重载:可定义同名但参数不同的槽函数。

    • 参数匹配:槽的参数需与信号参数兼容(数量 ≤ 信号参数,类型顺序一致)。

      // 信号:void signal(int a, double b);
      // 合法槽:void slot(int a);       // 忽略多余参数
      // 非法槽:void slot(double b);   // 类型不匹配

二、槽的使用规则

  1. 连接信号与槽
    • 通过 QObject::connect() 建立绑定,支持编译期类型检查(Qt5+ 语法):

      connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);
    • 连接类型(第五参数 Qt::ConnectionType):

      类型行为适用场景
      Qt::AutoConnection (默认)同线程→直接调用;跨线程→队列调用通用
      Qt::DirectConnection同步调用:槽在发送者线程立即执行单线程实时响应
      Qt::QueuedConnection异步调用:槽在接收者线程事件循环中执行跨线程通信(安全)
      Qt::BlockingQueuedConnection异步调用,但发送者线程阻塞直到槽完成线程间同步
      Qt::UniqueConnection避免重复连接(需与其他类型按位或)防止多次绑定
  2. 断开连接
    • 使用 disconnect() 手动解除绑定,防止悬空调用:

      disconnect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);
      

三、自定义槽的实践

  1. 实现要求

    • 必须实现函数体:与信号不同,槽需完整实现逻辑。

    • 支持多种形式:槽可以是成员函数、静态函数、全局函数或 Lambda 表达式。

      // Lambda 作为槽
      connect(button, &QPushButton::clicked, [=]() {qDebug() << "Button clicked via Lambda!";
      });
  2. 线程安全实践

    • 跨线程通信:必须使用 Qt::QueuedConnection,避免直接访问接收者线程资源:

      // 对象 worker 在子线程,mainWidget 在主线程
      connect(worker, &Worker::resultReady, mainWidget, &MainWidget::handleResult, Qt::QueuedConnection);

四、注意事项

  1. 资源管理
    • 对象销毁前调用 disconnect(),或使用 QPointer 智能指针防止野指针。
    • 避免槽中执行阻塞操作,耗时任务应移至 QThread 或线程池。
  2. 元对象系统依赖
    • 包含槽的类必须声明 Q_OBJECT,否则 moc 无法生成元代码。
    • 信号/槽参数类型需被 Qt 元类型系统支持(基本类型或 qRegisterMetaType() 注册的类型)。

总结

  • 核心定位:槽是 Qt 信号-槽机制的响应端,通过松耦合设计实现对象间通信。
  • 灵活扩展:支持重载、多线程安全连接、Lambda 表达式等现代 C++ 特性。
  • 性能权衡:虽比直接函数调用慢约 10 倍,但解耦优势在 GUI/异步场景中更为关键。

通过合理设计槽函数(如限制耗时操作、规范连接类型),可构建高效健壮的 Qt 应用。完整文档见 Qt 官方手册。

QObject::sender()

在 Qt 框架中,QObject::sender() 是一个关键函数,用于在槽函数内部获取触发当前槽的信号发送者对象指针。以下是其核心要点和使用详解:


核心功能

获取信号发送者

当槽函数被信号触发时,sender() 返回指向发送信号对象的指针(QObject* 类型)。若槽函数非由信号触发(如直接调用),则返回 nullptr。

http://www.dtcms.com/a/354743.html

相关文章:

  • Groovy集合常用简洁语法
  • linux mysql 数据库启动异常问题记录
  • KafKa学习笔记
  • AT_abc407_e [ABC407E] Most Valuable Parentheses
  • 前端开发中的CSS变量管理:实现缓存与响应式更新
  • 从 WPF 到 Avalonia 的迁移系列实战篇3:ResourceDictionary资源与样式的差异与迁移技巧
  • CuTe C++ 简介01,从示例开始
  • wpf之ListBox
  • 一个客户端直接掉线或断点,服务器怎么快速识别
  • 通过代码认识 CNN:用 PyTorch 实现卷积神经网络识别手写数字
  • audioMAE模型代码分析
  • 循环神经网络——pytorch实现循环神经网络(RNN、GRU、LSTM)
  • 深度学习——卷积神经网络(PyTorch 实现 MNIST 手写数字识别案例)
  • SpringBoot项目使用Liquibase 数据库版本管理
  • Day16_【机器学习—KNN算法】
  • IDA Pro 逆向分析快捷键大全及核心用法详解
  • 【Day 35】Linux-Mysql错误总结
  • 微信小程序对接EdgeX Foundry详细指南
  • 导入文件允许合并表格
  • 上海控安:汽车API安全-风险与防护策略解析
  • Elasticsearch数据迁移方案深度对比:三种方法的优劣分析
  • 领悟8种常见的设计模式
  • 74HC595芯片简析
  • OpenCV 基础操作实战指南:从图像处理到交互控制
  • Ubuntu有限网口无法使用解决方法
  • 企业级AI应用场景的核心特征
  • Fluent Bit针对kafka心跳重连机制详解(上)
  • DA14531(Cortex-M0+)之Wake-up Interrupt Controller (WIC)
  • JumpServer开源堡垒机:统一访问入口 + 安全管控 + 操作审计
  • 从0开始搭建一个前端项目(vue + vite + typescript)