【Qt】事件

🎬 个人主页艾莉丝努力练剑
专栏传送门 :《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录
Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬 艾莉丝的简介:


文章目录

  • 导入
  • [1 ~> 事件基本概念](#1 ~> 事件基本概念)
    • [1.1 事件与信号槽的本质关系](#1.1 事件与信号槽的本质关系)
    • [1.2 QEvent类体系](#1.2 QEvent类体系)
    • [1.3 事件的核心处理机制](#1.3 事件的核心处理机制)
  • [2 ~> 鼠标事件详解](#2 ~> 鼠标事件详解)
    • [2.1 鼠标进入与离开事件](#2.1 鼠标进入与离开事件)
      • [2.1.1 函数原型](#2.1.1 函数原型)
      • [2.1.2 完整实现步骤](#2.1.2 完整实现步骤)
    • [2.2 鼠标点击事件](#2.2 鼠标点击事件)
      • [2.2.1 函数原型与参数](#2.2.1 函数原型与参数)
      • [2.2.2 鼠标按键类型判断](#2.2.2 鼠标按键类型判断)
      • [2.2.3 实现代码](#2.2.3 实现代码)
    • [2.3 鼠标释放与双击事件](#2.3 鼠标释放与双击事件)
      • [2.3.1 鼠标释放事件](#2.3.1 鼠标释放事件)
      • [2.3.2 鼠标双击事件](#2.3.2 鼠标双击事件)
      • [2.3.3 重要注意事项](#2.3.3 重要注意事项)
    • [2.4 鼠标移动事件](#2.4 鼠标移动事件)
      • [2.4.1 默认行为与鼠标追踪](#2.4.1 默认行为与鼠标追踪)
      • [2.4.2 实现代码](#2.4.2 实现代码)
    • [2.5 鼠标滚轮事件](#2.5 鼠标滚轮事件)
      • [2.5.1 函数原型与delta()方法](#2.5.1 函数原型与delta()方法)
      • [2.5.2 累计滚动距离实现](#2.5.2 累计滚动距离实现)
  • [3 ~> 键盘事件详解](#3 ~> 键盘事件详解)
    • [3.1 键盘事件的触发条件](#3.1 键盘事件的触发条件)
    • [3.2 单个按键的捕获与判断](#3.2 单个按键的捕获与判断)
    • [3.3 组合键(快捷键)的处理](#3.3 组合键(快捷键)的处理)
    • [3.4 与QShortCut的对比](#3.4 与QShortCut的对比)
  • [4 ~> 定时器事件详解](#4 ~> 定时器事件详解)
    • [4.1 QTimerEvent的使用](#4.1 QTimerEvent的使用)
      • [4.2.1 核心函数](#4.2.1 核心函数)
      • [4.2.2 定时器ID的作用](#4.2.2 定时器ID的作用)
      • [4.2.3 倒计时功能完整实现](#4.2.3 倒计时功能完整实现)
    • [4.3 QTimer与QTimerEvent的对比](#4.3 QTimer与QTimerEvent的对比)
  • [5 ~> 窗口事件详解](#5 ~> 窗口事件详解)
    • [5.1 窗口移动事件moveEvent](#5.1 窗口移动事件moveEvent)
    • [5.2 窗口大小改变事件resizeEvent](#5.2 窗口大小改变事件resizeEvent)
  • [6 ~> 事件分发器简介](#6 ~> 事件分发器简介)
    • [6.1 事件分发器的工作原理](#6.1 事件分发器的工作原理)
    • [6.2 event()函数的作用](#6.2 event()函数的作用)
    • [6.3 使用注意事项](#6.3 使用注意事项)
  • 全文总结
  • 结尾


导入

思维导图

bash 复制代码
Qt事件机制
├─ 1 事件基本概念
│  ├─ 1.1 事件与信号槽关系
│  │  ├─ 信号槽是事件的上层封装
│  │  ├─ 事件是信号槽的底层机制
│  │  └─ 特殊场景需直接使用事件
│  ├─ 1.2 QEvent类体系
│  │  ├─ 基类QEvent
│  │  ├─ 子类:QMouseEvent/QKeyEvent等
│  │  └─ 事件对象携带交互信息
│  ├─ 1.3 常见事件类型
│  │  ├─ 鼠标/键盘/定时器事件
│  │  ├─ 进入离开/滚轮/绘屏事件
│  │  └─ 窗口移动/大小改变/焦点事件
│  └─ 1.4 事件处理核心
│     ├─ 重写父类虚函数
│     ├─ 利用C++多态机制
│     └─ 控件提升为自定义类
├─ 2 鼠标事件详解
│  ├─ 2.1 进入离开事件
│  │  ├─ enterEvent()/leaveEvent()
│  │  └─ 控件提升操作步骤
│  ├─ 2.2 点击事件mousePressEvent
│  │  ├─ 局部坐标x()/y()
│  │  ├─ 全局坐标globalX()/globalY()
│  │  └─ 按键类型判断Qt::MouseButton
│  ├─ 2.3 释放与双击事件
│  │  ├─ mouseReleaseEvent()
│  │  ├─ mouseDoubleClickEvent()
│  │  └─ 单击与双击冲突问题
│  ├─ 2.4 移动事件mouseMoveEvent
│  │  ├─ 默认不追踪鼠标移动
│  │  └─ setMouseTracking(true)开启
│  └─ 2.5 滚轮事件wheelEvent
│     ├─ delta()获取滚动距离
│     └─ 累计滚动实现功能
├─ 3 键盘事件详解
│  ├─ 3.1 keyPressEvent()/keyReleaseEvent()
│  ├─ 3.2 单个按键判断Qt::Key_*枚举
│  ├─ 3.3 组合键处理modifiers()
│  │  └─ Qt::ControlModifier/ShiftModifier
│  └─ 3.4 与QShortCut的对比
├─ 4 定时器事件详解
│  ├─ 4.1 两种实现方式
│  │  ├─ QTimer(高层接口,推荐)
│  │  └─ QTimerEvent(底层事件)
│  ├─ 4.2 QTimerEvent核心
│  │  ├─ startTimer(ms)返回timerId
│  │  ├─ killTimer(timerId)停止
│  │  └─ timerEvent()中区分定时器
│  └─ 4.3 倒计时功能完整实现
├─ 5 窗口事件详解
│  ├─ 5.1 moveEvent()窗口移动
│  │  └─ oldPos()/pos()获取新旧位置
│  └─ 5.2 resizeEvent()大小改变
│     └─ oldSize()/size()获取新旧尺寸
└─ 6 事件分发器
   ├─ 6.1 所有事件经event()函数分发
   ├─ 6.2 可重写event()拦截所有事件
   └─ 6.3 使用不当会影响原有逻辑

导入语

Qt作为主流的GUI开发框架,其核心交互能力建立在事件机制之上。我们日常使用的按钮点击、文本输入、窗口拖动等所有用户交互,本质上都是操作系统产生事件,再由Qt封装并传递给应用程序处理的过程。虽然绝大多数场景下我们使用更便捷的信号槽机制就能完成开发,但当需要实现高度自定义的交互效果------比如自定义按钮的悬停动画、全局键盘快捷键拦截、鼠标拖拽绘制图形、精准的定时器控制等------信号槽就显得力不从心,此时必须深入到事件机制层面进行开发。

本文将系统梳理Qt事件机制的完整知识体系,从事件与信号槽的本质关系入手,详细讲解各类常见事件的处理方法、代码实现和注意事项,最后介绍事件分发器的工作原理。所有内容均结合实际开发案例,确保学完后既能理解底层逻辑,又能直接应用到项目中。


1 ~> 事件基本概念

1.1 事件与信号槽的本质关系

用户的所有操作(点击鼠标、按下键盘、移动窗口等)都会先产生操作系统级别的事件,Qt将这些原生事件进行了第一层封装,形成了Qt的事件体系。在此基础上,Qt为了简化开发,又对常用事件进行了第二层封装,得到了我们熟悉的信号槽机制。

  • 本质关系 :信号槽是事件的进一步封装,事件是信号槽的底层支撑。例如按钮的clicked()信号,本质上就是mousePressEventmouseReleaseEvent两个事件的组合。
  • 使用场景
    • 90%以上的常规交互使用信号槽即可完成,代码更简洁易维护
    • 当Qt没有提供对应信号、或需要实现高度自定义的交互逻辑时,必须直接使用事件机制
    • 事件机制允许开发者进行更深度的定制化开发,实现信号槽无法完成的功能

1.2 QEvent类体系

Qt中所有事件都继承自QEvent基类,不同类型的事件由对应的子类表示,每个事件对象都会携带本次交互的详细信息。

核心事件子类及对应场景:

事件子类 触发场景 携带的核心信息
QMouseEvent 鼠标点击、移动、释放 坐标位置、按下的按键、全局/局部坐标
QKeyEvent 键盘按键按下、释放 按键编码、修饰键(Ctrl/Shift等)
QTimerEvent 定时器时间到达 定时器ID
QWheelEvent 鼠标滚轮滚动 滚动距离、滚动方向
QPaintEvent 窗口需要重绘 重绘区域
QMoveEvent 窗口位置移动 新旧位置坐标
QResizeEvent 窗口大小改变 新旧尺寸

1.3 事件的核心处理机制

Qt中处理事件的核心方法是重写父类的虚事件处理函数,这依赖于C++的多态机制:

  1. 创建自定义类,继承自Qt提供的标准控件类(如QLabel、QWidget、QPushButton等)
  2. 在自定义类中重写父类对应的虚事件处理函数(如enterEvent()mousePressEvent()等)
  3. 将UI设计器中拖放的标准控件提升为自定义类的实例
  4. 当事件触发时,Qt会通过多态机制自动调用我们重写的函数

注意:重写事件函数时,必须保证函数名、参数类型和个数与父类完全一致,否则无法触发多态。特别注意函数名的大小写,Qt的事件函数均以小写字母开头。


2 ~> 鼠标事件详解

鼠标事件是GUI开发中最常用的事件类型,涵盖了鼠标的进入、离开、点击、移动、滚轮等所有操作。

2.1 鼠标进入与离开事件

用于检测鼠标光标进入或离开某个控件的区域,常用于实现悬停效果、提示信息等。

2.1.1 函数原型

cpp 复制代码
// 鼠标进入控件时触发
[virtual protected] void QWidget::enterEvent(QEvent *event);
// 鼠标离开控件时触发
[virtual protected] void QWidget::leaveEvent(QEvent *event);

2.1.2 完整实现步骤

  1. 创建自定义Label类,继承自QLabel
    1. 头文件label.h
cpp 复制代码
#ifndef LABEL_H
#define LABEL_H
#include <QLabel>

class Label : public QLabel
{
    Q_OBJECT
public:
    Label(QWidget *parent = nullptr);

protected:
    void enterEvent(QEvent *event) override;
    void leaveEvent(QEvent *event) override;
};

#endif // LABEL_H
  • 源文件label.cpp
cpp 复制代码
#include "label.h"
#include <QDebug>

Label::Label(QWidget *parent) : QLabel(parent)
{
}

void Label::enterEvent(QEvent *event)
{
    (void)event; // 消除未使用参数的警告
    qDebug() << "鼠标进入Label区域";
}

void Label::leaveEvent(QEvent *event)
{
    (void)event;
    qDebug() << "鼠标离开Label区域";
}
  1. 控件提升操作
    1. 在UI设计器中拖放一个QLabel控件
    2. 右键点击该控件,选择"提升为"
    3. 在弹出的对话框中,基类名称选择"QLabel",提升的类名称填写"Label",头文件填写"label.h"
    4. 点击"添加",然后点击"提升"
    5. 此时UI中的QLabel就变成了我们自定义的Label类实例,运行程序即可看到效果

2.2 鼠标点击事件

用于捕获鼠标按键的按下操作,可以获取点击位置和按下的按键类型。

2.2.1 函数原型与参数

cpp 复制代码
[virtual protected] void QWidget::mousePressEvent(QMouseEvent *event);

参数QMouseEvent* event携带了本次点击的所有信息:

  • event->x() / event->y():点击位置相对于控件左上角的局部坐标
  • event->globalX() / event->globalY():点击位置相对于屏幕左上角的全局坐标
  • event->button():返回按下的鼠标按键,类型为Qt::MouseButton枚举

2.2.2 鼠标按键类型判断

Qt::MouseButton枚举定义了所有支持的鼠标按键:

cpp 复制代码
Qt::LeftButton    // 左键 0x00000001
Qt::RightButton   // 右键 0x00000002
Qt::MiddleButton  // 中键(滚轮)0x00000004
Qt::BackButton    // 侧键后退 0x00000008
Qt::ForwardButton // 侧键前进 0x00000010

2.2.3 实现代码

在自定义Label类中添加:

cpp 复制代码
// label.h
protected:
    void mousePressEvent(QMouseEvent *event) override;

// label.cpp
#include <QMouseEvent>

void Label::mousePressEvent(QMouseEvent *event)
{
    // 判断按下的按键
    if (event->button() == Qt::LeftButton) {
        qDebug() << "按下鼠标左键";
    } else if (event->button() == Qt::RightButton) {
        qDebug() << "按下鼠标右键";
    } else if (event->button() == Qt::MiddleButton) {
        qDebug() << "按下鼠标中键";
    }

    // 输出坐标信息
    qDebug() << "局部坐标:" << event->x() << "," << event->y();
    qDebug() << "全局坐标:" << event->globalX() << "," << event->globalY();
}

2.3 鼠标释放与双击事件

2.3.1 鼠标释放事件

cpp 复制代码
// 函数原型
[virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event);

// 实现代码
void Label::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        qDebug() << "释放鼠标左键";
    } else if (event->button() == Qt::RightButton) {
        qDebug() << "释放鼠标右键";
    }
}

2.3.2 鼠标双击事件

cpp 复制代码
// 函数原型
[virtual protected] void QWidget::mouseDoubleClickEvent(QMouseEvent *event);

// 实现代码
void Label::mouseDoubleClickEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        qDebug() << "双击鼠标左键";
    }
}

2.3.3 重要注意事项

双击操作会先触发两次单击事件(按下+释放),然后才触发双击事件。如果同时实现了单击和双击逻辑,需要注意避免冲突,例如可以通过定时器延迟判断是单击还是双击。

2.4 鼠标移动事件

用于实时获取鼠标的移动位置,常用于实现拖拽、绘制等功能。

2.4.1 默认行为与鼠标追踪

Qt默认情况下不会追踪鼠标移动,只有当鼠标按键按下时才会触发mouseMoveEvent。如果需要在鼠标未按下时也能追踪移动,必须显式开启鼠标追踪:

cpp 复制代码
// 在控件的构造函数中添加
this->setMouseTracking(true);

2.4.2 实现代码

cpp 复制代码
// widget.h
protected:
    void mouseMoveEvent(QMouseEvent *event) override;

// widget.cpp
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setMouseTracking(true); // 开启鼠标追踪
}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    qDebug() << "鼠标移动到:" << event->x() << "," << event->y();
}

注意:鼠标移动事件触发频率非常高,如果在处理函数中执行复杂逻辑,可能会导致程序卡顿,应尽量优化处理逻辑。

2.5 鼠标滚轮事件

用于捕获鼠标滚轮的滚动操作,常用于实现缩放、滚动列表等功能。

2.5.1 函数原型与delta()方法

cpp 复制代码
[virtual protected] void QWidget::wheelEvent(QWheelEvent *event);

event->delta()返回滚轮滚动的距离,单位为1/8度:

  • 向上滚动:返回正值(通常为120)
  • 向下滚动:返回负值(通常为-120)

2.5.2 累计滚动距离实现

cpp 复制代码
// widget.h
private:
    int totalDelta = 0;

protected:
    void wheelEvent(QWheelEvent *event) override;

// widget.cpp
#include <QWheelEvent>

void Widget::wheelEvent(QWheelEvent *event)
{
    totalDelta += event->delta();
    qDebug() << "本次滚动距离:" << event->delta();
    qDebug() << "累计滚动距离:" << totalDelta;
}

3 ~> 键盘事件详解

键盘事件用于捕获用户的键盘输入,支持单个按键和组合键的处理。

3.1 键盘事件的触发条件

键盘事件只有在控件或窗口处于激活状态时才会触发。如果焦点在其他控件或程序上,键盘事件会被其他程序捕获。

3.2 单个按键的捕获与判断

cpp 复制代码
// 函数原型
[virtual protected] void QWidget::keyPressEvent(QKeyEvent *event);
[virtual protected] void QWidget::keyReleaseEvent(QKeyEvent *event);

event->key()返回按下的按键编码,对应Qt::Key_*枚举:

cpp 复制代码
// 实现代码
#include <QKeyEvent>

void Widget::keyPressEvent(QKeyEvent *event)
{
    qDebug() << "按下按键编码:" << event->key();

    // 判断具体按键
    if (event->key() == Qt::Key_A) {
        qDebug() << "按下了A键";
    } else if (event->key() == Qt::Key_Escape) {
        qDebug() << "按下了ESC键";
        this->close(); // 按下ESC关闭窗口
    }
}

3.3 组合键(快捷键)的处理

使用event->modifiers()获取修饰键状态,对应Qt::KeyboardModifier枚举:

  • Qt::ControlModifier:Ctrl键
  • Qt::ShiftModifier:Shift键
  • Qt::AltModifier:Alt键
cpp 复制代码
// 处理Ctrl + A组合键
void Widget::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_A && event->modifiers() == Qt::ControlModifier) {
        qDebug() << "按下了Ctrl+A组合键";
        // 实现全选逻辑
    }
}

3.4 与QShortCut的对比

  • 对于简单的快捷键功能,推荐使用QShortCut类(信号槽机制),代码更简洁
  • 当需要处理复杂的键盘逻辑(如连续按键、按键长按等)时,使用键盘事件更灵活

4 ~> 定时器事件详解

定时器用于周期性执行任务,常用于实现动画、倒计时、定时刷新等功能。Qt提供了两种定时器实现方式:高层接口QTimer和底层事件QTimerEvent

4.1 QTimerEvent的使用

QTimerEvent是Qt定时器的底层实现,所有定时器最终都会触发该事件。

4.2.1 核心函数

  • int startTimer(int interval):开启定时器,参数为间隔时间(毫秒),返回唯一的定时器ID
  • void killTimer(int id):根据定时器ID停止定时器
  • void timerEvent(QTimerEvent *event):定时器事件处理函数,所有定时器触发时都会调用该函数

4.2.2 定时器ID的作用

  • 每个startTimer调用都会返回一个唯一的ID,用于区分不同的定时器
  • 定时器ID类似于Linux中的文件描述符,是定时器的身份标识
  • 当程序中有多个定时器时,必须在timerEvent中通过ID判断是哪个定时器触发

4.2.3 倒计时功能完整实现

cpp 复制代码
// widget.h
private:
    Ui::Widget *ui;
    int timerId; // 保存定时器ID

protected:
    void timerEvent(QTimerEvent *event) override;

// widget.cpp
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 设置LCD初始值为10
    ui->lcdNumber->display(10);
    // 开启1秒间隔的定时器
    timerId = this->startTimer(1000);
}

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

void Widget::timerEvent(QTimerEvent *event)
{
    // 区分定时器
    if (event->timerId() != this->timerId) {
        return; // 不是我们的定时器,直接忽略
    }

    // 获取当前LCD显示的数值
    int value = ui->lcdNumber->intValue();
    if (value <= 0) {
        // 倒计时结束,停止定时器
        this->killTimer(this->timerId);
        qDebug() << "倒计时结束";
        return;
    }

    // 数值减1并更新显示
    value--;
    ui->lcdNumber->display(value);
}

4.3 QTimer与QTimerEvent的对比

  • QTimer:高层接口,使用信号槽机制,每个定时器对应一个对象,代码更清晰易维护,是实际开发中的首选
  • QTimerEvent:底层事件,需要手动管理定时器ID,多个定时器共用一个处理函数,代码相对复杂,但更灵活

5 ~> 窗口事件详解

窗口事件用于捕获窗口的位置和大小变化,常用于实现自适应布局、窗口状态监控等功能。

5.1 窗口移动事件moveEvent

当窗口被拖动改变位置时触发:

cpp 复制代码
// 函数原型
[virtual protected] void QWidget::moveEvent(QMoveEvent *event);

// 实现代码
#include <QMoveEvent>

void Widget::moveEvent(QMoveEvent *event)
{
    qDebug() << "窗口旧位置:" << event->oldPos();
    qDebug() << "窗口新位置:" << event->pos();
}

5.2 窗口大小改变事件resizeEvent

当窗口被拖动改变大小时触发:

cpp 复制代码
// 函数原型
[virtual protected] void QWidget::resizeEvent(QResizeEvent *event);

// 实现代码
#include <QResizeEvent>

void Widget::resizeEvent(QResizeEvent *event)
{
    qDebug() << "窗口旧尺寸:" << event->oldSize();
    qDebug() << "窗口新尺寸:" << event->size();
    qDebug() << "新宽度:" << event->size().width();
    qDebug() << "新高度:" << event->size().height();
}

6 ~> 事件分发器简介

6.1 事件分发器的工作原理

Qt中所有事件都会先传递到QObject::event()函数,该函数是事件分发的总入口。它不会直接处理事件,而是根据事件的类型(event->type())调用对应的具体事件处理函数(如mousePressEvent()keyPressEvent()等)。

6.2 event()函数的作用

我们可以重写event()函数,在事件分发之前拦截所有事件,实现全局的事件处理或过滤:

cpp 复制代码
bool Widget::event(QEvent *event)
{
    // 拦截所有鼠标按下事件
    if (event->type() == QEvent::MouseButtonPress) {
        qDebug() << "拦截到鼠标按下事件";
        // 返回true表示事件已处理,不再向下分发
        return true;
    }

    // 其他事件交给父类处理
    return QWidget::event(event);
}

6.3 使用注意事项

  • 重写event()函数会影响所有事件的分发,使用不当会破坏Qt原有的事件体系
  • 除非有特殊需求,否则不建议重写该函数
  • 如果确实需要拦截事件,一定要记得将不需要处理的事件交给父类的event()函数处理

全文总结

本文系统梳理了Qt事件机制的完整知识体系,核心重点总结如下:

  1. 本质关系:信号槽是事件的上层封装,事件是信号槽的底层支撑。常规场景用信号槽,自定义场景用事件。
  2. 核心处理方式:通过继承标准控件类,重写对应的虚事件处理函数,再将UI控件提升为自定义类实例。
  3. 鼠标事件
    1. 进入离开:enterEvent()/leaveEvent()
    2. 点击释放:mousePressEvent()/mouseReleaseEvent(),可获取局部/全局坐标和按键类型
    3. 移动事件:默认不追踪,需调用setMouseTracking(true)开启
    4. 滚轮事件:wheelEvent(),通过delta()获取滚动距离
  4. 键盘事件keyPressEvent()/keyReleaseEvent(),通过key()判断单个按键,modifiers()判断组合键。
  5. 定时器事件
    1. 高层接口QTimer(推荐),底层事件QTimerEvent
    2. QTimerEvent需手动管理定时器ID,在timerEvent()中区分不同定时器
  6. 窗口事件moveEvent()捕获位置变化,resizeEvent()捕获大小变化。
  7. 事件分发器 :所有事件经event()函数分发,可重写该函数拦截事件,但需谨慎使用。

实际开发中,应遵循"优先使用信号槽,必要时使用事件"的原则,在保证代码简洁性的同时,实现所需的功能效果。掌握事件机制是深入Qt开发的必经之路,它能让你真正理解GUI程序的交互本质,实现更灵活、更强大的自定义控件和交互效果。


结尾

uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ### 艾莉丝努力练剑 C/C++ & Linux 底层探索者 | 一个正在努力练剑的技术博主 *** ** * ** *** 👀 【关注】 跟随我一起深耕技术领域,见证每一次成长。 ❤️ 【点赞】 让优质内容被更多人看见,让知识传递更有力量。 ⭐ 【收藏】 把核心知识点存好,在需要时随时查、随时用。 💬 【评论】 分享你的经验或疑问,评论区一起交流避坑! 不要忘记给博主"一键四连"哦! "今日练剑达成!" "技术之路难免有困惑,但同行的人会让前进更有方向。" |

结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主"一键四连"哦!

往期回顾

【QT】窗口

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡 ૮₍ ˶ ˊ ᴥ ˋ˶₎ა

相关推荐
PersistJiao1 小时前
python环境下免费、专业的中英翻译
开发语言·windows·python·机器翻译
rqtz1 小时前
【C++】源码编译 Qt5.15.3|Ubuntu22.04 下 ROS 开发环境搭建
开发语言·c++·qt·ros
weixin_604236671 小时前
华为企业级路由器完整版实战配置
网络·安全·华为·智能路由器·华为交换机命令·华为路由器
Bert.Cai1 小时前
Oracle简介
数据库·oracle
洛水水1 小时前
图床项目实现:注册登录 + 文件上传等功能的完善
网络·c++·mysql·图床
Jun6261 小时前
QT(9)-Qjson移植
开发语言·qt
施棠海1 小时前
自定义并可深度定制的数字滚动选择器完整源代码与相关注意事项
java·开发语言
呉師傅1 小时前
联想M7400Pro提示无法打印0B 关闭电源然后重新打开故障维修分享
运维·网络·windows·电脑
名不经传的养虾人1 小时前
从0到1:企业级AI项目迭代日记 Vol.41|多租户不是一个功能,是一次手术
服务器·数据库·系统架构·ai编程·ai工作流·企业ai