news 2026/5/1 8:24:14

DISCO-F469NI嵌入式LCD触摸驱动C++封装库

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DISCO-F469NI嵌入式LCD触摸驱动C++封装库

1. 项目概述

DISCOF469LCD 是一个面向 STMicroelectronics DISCO-F469NI 开发板的触摸式 LCD 显示驱动封装库。该库并非从零实现底层硬件控制,而是基于 ST 官方提供的 BSP(Board Support Package)层进行面向对象的 C++ 封装,旨在为嵌入式应用开发者提供更简洁、可复用、易维护的图形界面开发接口。其核心价值在于:将 BSP 中分散的初始化、绘图、触摸处理等 C 函数调用,统一抽象为具有明确职责边界的类成员函数,并通过 RAII(Resource Acquisition Is Initialization)机制自动管理显示资源生命周期

DISCO-F469NI 板载一块 4.3 英寸 WVGA(480×272)RGB TFT-LCD 屏幕,集成电容式触摸控制器(STMP32F469I-DISCO 自带的 FT5336 或兼容芯片),并由 STM32F469NI 微控制器通过 LTDC(LCD-TFT Display Controller)、DMA2D(2D Graphics Accelerator)和 FMC(Flexible Memory Controller)协同驱动。原生 BSP 提供了BSP_LCD_Init()BSP_LCD_Clear()BSP_LCD_DrawPixel()BSP_TS_Init()等一系列 C 风格函数,但缺乏状态管理、错误传播、资源自动释放等现代嵌入式 C++ 工程实践要素。DISCOF469LCD 正是为弥补这一缺口而设计。

该库严格遵循“零开销抽象”原则——所有封装不引入运行时性能损耗。所有成员函数均为inline或直接内联调用 BSP API;类实例仅持有少量状态变量(如当前屏幕尺寸、触摸使能标志、颜色格式),无动态内存分配;构造/析构过程仅执行必要的 BSP 初始化与反初始化,不涉及复杂逻辑。其本质是一个轻量级胶水层,目标是让开发者在main()中只需三行代码即可点亮屏幕并响应触摸:

DISCOF469LCD lcd; lcd.init(); lcd.draw_string(10, 10, "Hello DISCO-F469NI!", LCD_COLOR_WHITE);

2. 硬件架构与 BSP 依赖关系

2.1 DISCO-F469NI 显示子系统拓扑

DISCO-F469LCD 的功能实现深度依赖于 DISCO-F469NI 硬件平台的显示架构,其数据流路径如下:

  1. CPU(Cortex-M4):执行应用程序逻辑,调用 DISCOF469LCD 类方法。
  2. LTDC(LCD-TFT Display Controller):专用硬件模块,负责从外部 SDRAM(通过 FMC 接口)读取帧缓冲区(Frame Buffer)数据,按配置的时序生成 RGB 并行信号,驱动 LCD 面板。LTDC 支持多层叠加、Alpha 混合、色彩空间转换。
  3. DMA2D(2D Graphics Accelerator):硬件加速器,用于执行矩形填充、位图拷贝、颜色格式转换(如 ARGB8888 → RGB565)、Alpha 混合等操作,极大减轻 CPU 负担。BSP 中的BSP_LCD_DrawRect()BSP_LCD_DrawBitmap()等函数内部即调用 DMA2D。
  4. FMC(Flexible Memory Controller):配置为连接外部 32MB SDRAM(IS42S32800J),作为 LTDC 的帧缓冲区存储介质。DISCO-F469NI 的 SDRAM 地址映射为0xC0000000起始。
  5. LCD 面板与触摸控制器:480×272 分辨率 TFT 屏,通过 16-bit RGB 接口连接 LTDC;电容式触摸由 FT5336 控制器处理,通过 I2C 总线(I2C1)与 MCU 通信,中断引脚TS_INT(PA15)通知触摸事件。

DISCOF469LCD 不直接操作 LTDC/DMA2D 寄存器,而是完全复用 ST 提供的stm32f469i_discovery_lcd.c/hstm32f469i_discovery_ts.c/h文件中的 BSP 函数。这意味着其稳定性与 ST 官方 BSP 保持一致,且可无缝集成到 STM32CubeMX 生成的工程中。

2.2 BSP API 依赖清单

DISCOF469LCD 的所有功能均构建于以下 BSP 函数之上,这些函数定义在Drivers/BSP/STM32F469I-Discovery/stm32f469i_discovery_lcd.cstm32f469i_discovery_ts.c中:

BSP 函数功能说明DISCOF469LCD 封装点
BSP_LCD_Init()初始化 LTDC、DMA2D、FMC 及 LCD 面板时序DISCOF469LCD::init()
BSP_LCD_GetXSize(),BSP_LCD_GetYSize()获取当前分辨率DISCOF469LCD::get_width(),get_height()
BSP_LCD_Clear(LCD_COLOR_BLACK)清屏DISCOF469LCD::clear()
BSP_LCD_SetTextColor(),BSP_LCD_SetBackColor()设置前景/背景色DISCOF469LCD::set_text_color(),set_back_color()
BSP_LCD_DisplayOn(),BSP_LCD_DisplayOff()开/关显示DISCOF469LCD::display_on(),display_off()
BSP_LCD_DrawPixel(x, y, color)绘制单像素DISCOF469LCD::draw_pixel()
BSP_LCD_DrawLine(x1,y1,x2,y2)绘制直线DISCOF469LCD::draw_line()
BSP_LCD_DrawRect(x,y,w,h)绘制空心矩形DISCOF469LCD::draw_rect()
BSP_LCD_FillRect(x,y,w,h)填充实心矩形DISCOF469LCD::fill_rect()
BSP_LCD_DrawCircle(x,y,r)绘制圆DISCOF469LCD::draw_circle()
BSP_LCD_FillCircle(x,y,r)填充圆DISCOF469LCD::fill_circle()
BSP_LCD_DrawBitmap(x,y, bitmap)绘制位图DISCOF469LCD::draw_bitmap()
BSP_LCD_DisplayStringAt(x,y, str, mode)在指定位置显示字符串DISCOF469LCD::draw_string()
BSP_TS_Init()初始化触摸控制器 FT5336DISCOF469LCD::init_touch()
BSP_TS_GetState(&state)获取触摸状态(坐标、触点数)DISCOF469LCD::get_touch_state()

关键设计考量:DISCOF469LCD 并未重新实现任何绘图算法,所有draw_*方法均是对 BSP 对应函数的直接封装。这种设计确保了:

  • 性能零损耗:无额外函数调用开销,编译器可内联优化;
  • 行为一致性:与 ST 官方例程行为完全相同,避免因算法差异导致的显示异常;
  • 维护性:当 ST 更新 BSP 修复 LTDC 时序或 DMA2D bug 时,DISCOF469LCD 自动受益。

3. 类接口设计与核心 API 解析

3.1 类声明与构造/析构语义

DISCOF469LCD类采用单例模式(非强制,但推荐全局唯一实例)设计,其头文件discof469lcd.h定义如下:

#ifndef __DISCOF469LCD_H #define __DISCOF469LCD_H #include "stm32f4xx_hal.h" #include "stm32f469i_discovery.h" #include "stm32f469i_discovery_lcd.h" #include "stm32f469i_discovery_ts.h" class DISCOF469LCD { public: // 构造函数:仅初始化内部状态,不执行硬件初始化 DISCOF469LCD(); // 析构函数:自动调用 BSP 反初始化,确保资源释放 ~DISCOF469LCD(); // 主要功能接口 bool init(); // 初始化 LCD 硬件 void clear(uint32_t color = LCD_COLOR_BLACK); // 清屏 void display_on(); // 开启显示 void display_off(); // 关闭显示 uint16_t get_width() const; // 获取宽度(px) uint16_t get_height() const; // 获取高度(px) // 颜色与文本设置 void set_text_color(uint32_t color); // 设置文本前景色 void set_back_color(uint32_t color); // 设置文本背景色 // 基础绘图 void draw_pixel(uint16_t x, uint16_t y, uint32_t color); void draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint32_t color); void draw_rect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color); void fill_rect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color); void draw_circle(uint16_t x, uint16_t y, uint16_t r, uint32_t color); void fill_circle(uint16_t x, uint16_t y, uint16_t r, uint32_t color); // 高级绘图 void draw_bitmap(uint16_t x, uint16_t y, const uint16_t *bitmap, uint16_t w, uint16_t h); void draw_string(uint16_t x, uint16_t y, const char *str, uint32_t mode = CENTER_MODE); // 触摸功能 bool init_touch(); // 初始化触摸控制器 bool is_touch_enabled() const; // 查询触摸是否已启用 bool get_touch_state(TS_State_t *state); // 获取触摸状态 private: bool _touch_enabled; // 内部状态:触摸是否已初始化 }; #endif /* __DISCOF469LCD_H */

构造/析构语义解析

  • 构造函数DISCOF469LCD():仅执行this->_touch_enabled = false;,不调用任何 BSP 函数。这是关键设计——避免在全局对象构造时(早于HAL_Init())执行硬件操作,防止未初始化外设导致 HardFault。
  • 析构函数~DISCOF469LCD():调用BSP_LCD_DeInit()BSP_TS_DeInit()(若触摸已启用)。这体现了 RAII 核心思想:资源获取(init())与释放(析构)成对出现,即使在异常路径下也能保证资源清理,杜绝内存/外设泄漏。

3.2 核心 API 实现逻辑剖析

bool DISCOF469LCD::init()

此函数是使用该库的第一步,其内部流程严格遵循 ST BSP 初始化顺序:

bool DISCOF469LCD::init() { // 1. 调用 BSP 初始化 LCD if (BSP_LCD_Init() != LCD_OK) { return false; // 初始化失败,返回 false } // 2. 同步设置默认颜色(BSP 默认为 WHITE/BLACK,但显式设置更安全) BSP_LCD_SetTextColor(LCD_COLOR_WHITE); BSP_LCD_SetBackColor(LCD_COLOR_BLACK); // 3. 确保显示开启(BSP_Init 可能默认关闭) BSP_LCD_DisplayOn(); // 4. 清屏以提供干净画布 BSP_LCD_Clear(LCD_COLOR_BLACK); return true; }

工程要点BSP_LCD_Init()内部执行了完整的 LTDC/DMA2D/FMC/SDRAM 初始化序列,包括:

  • 配置 LTDC 时钟(RCC->APB2ENR |= RCC_APB2ENR_LTDCEN);
  • 初始化 FMC 控制器以访问 SDRAM;
  • 配置 LTDC Layer 0 的帧缓冲区地址(0xC0000000)、尺寸(480×272)、像素格式(LTDC_Pixelformat_RGB565);
  • 启动 LTDC 并使能显示。
void DISCOF469LCD::draw_string(...)

该函数封装了 BSP 的BSP_LCD_DisplayStringAt(),但增加了对mode参数的灵活支持:

void DISCOF469LCD::draw_string(uint16_t x, uint16_t y, const char *str, uint32_t mode) { if (mode == CENTER_MODE) { // 计算字符串宽度(需预知字体宽度,此处假设 16x24 字体) uint16_t str_width = strlen(str) * 16; uint16_t center_x = (get_width() - str_width) / 2; BSP_LCD_DisplayStringAt(center_x, y, (uint8_t*)str, LEFT_MODE); } else if (mode == RIGHT_MODE) { uint16_t str_width = strlen(str) * 16; uint16_t right_x = get_width() - str_width; BSP_LCD_DisplayStringAt(right_x, y, (uint8_t*)str, LEFT_MODE); } else { BSP_LCD_DisplayStringAt(x, y, (uint8_t*)str, mode); } }

参数说明表

参数类型取值范围说明
x,yuint16_t0 ≤ x < width,0 ≤ y < height文本左上角起始坐标
strconst char*NUL-terminatedASCII 字符串指针
modeuint32_tLEFT_MODE,CENTER_MODE,RIGHT_MODE文本对齐模式(CENTER_MODE/RIGHT_MODE为 DISCOF469LCD 扩展)
bool DISCOF469LCD::get_touch_state(TS_State_t *state)

触摸功能是 DISCOF469LCD 的重要扩展,其封装了 FT5336 的轮询式读取:

bool DISCOF469LCD::get_touch_state(TS_State_t *state) { if (!_touch_enabled) { return false; // 触摸未初始化,拒绝调用 } // BSP_TS_GetState 返回 0 表示成功,非 0 表示错误(如 I2C timeout) return (BSP_TS_GetState(state) == TS_OK); }

TS_State_t结构体定义在stm32f469i_discovery_ts.h中,包含:

  • touchDetected: 布尔值,指示是否有触摸发生;
  • touchX[5],touchY[5]: 五个触点的 X/Y 坐标数组(FT5336 支持最多 5 点);
  • touchWeight[5]: 各触点压力权重(模拟值);
  • touchEventId[5]: 事件 ID(TOUCH_EVENT_PRESS,TOUCH_EVENT_MOVE,TOUCH_EVENT_RELEASE)。

工程实践建议:在 FreeRTOS 环境中,不应在任务中频繁轮询get_touch_state()。推荐方案是:

  1. init_touch()后,配置TS_INT引脚为 EXTI 中断;
  2. 中断服务程序(ISR)中仅置位一个二值信号量(xSemaphoreGiveFromISR());
  3. 显示任务中xSemaphoreTake(touch_semaphore, portMAX_DELAY)等待信号量,再调用get_touch_state()读取数据。此举避免 CPU 空转,提升系统效率。

4. 典型应用示例与工程集成

4.1 基础显示:Hello World 与几何图形

以下代码展示了如何在裸机环境下(无 RTOS)快速启动 DISCOF469LCD:

#include "main.h" #include "discof469lcd.h" DISCOF469LCD lcd; // 全局实例 int main(void) { HAL_Init(); SystemClock_Config(); // 配置 180MHz SYSCLK, 90MHz AHB, 45MHz APB1/APB2 // 初始化 LCD if (!lcd.init()) { Error_Handler(); // 初始化失败处理 } // 绘制彩色边框 lcd.draw_rect(0, 0, 480, 272, LCD_COLOR_RED); lcd.draw_rect(5, 5, 470, 262, LCD_COLOR_GREEN); // 绘制中心圆 lcd.fill_circle(240, 136, 50, LCD_COLOR_BLUE); // 显示居中文字 lcd.set_text_color(LCD_COLOR_YELLOW); lcd.set_back_color(LCD_COLOR_BLUE); lcd.draw_string(0, 120, "DISCO-F469NI", CENTER_MODE); while (1) { HAL_Delay(1000); lcd.clear(LCD_COLOR_BLACK); lcd.draw_string(0, 100, "Tick...", CENTER_MODE); HAL_Delay(1000); lcd.clear(LCD_COLOR_BLACK); lcd.draw_string(0, 100, "Tock...", CENTER_MODE); } }

4.2 FreeRTOS 集成:触摸驱动的 UI 任务

在 FreeRTOS 环境中,DISCOF469LCD 可与任务、队列、信号量无缝协作。以下是一个触摸按钮响应的完整示例:

#include "FreeRTOS.h" #include "task.h" #include "semphr.h" #include "discof469lcd.h" DISCOF469LCD lcd; SemaphoreHandle_t touch_sem; // 触摸中断信号量 QueueHandle_t touch_queue; // 触摸坐标队列 // 触摸中断服务程序 (EXTI15_10_IRQHandler) void EXTI15_10_IRQHandler(void) { if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_15) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_15); xSemaphoreGiveFromISR(touch_sem, NULL); } } // 触摸处理任务 void touch_task(void *pvParameters) { TS_State_t ts; while (1) { // 等待触摸中断 if (xSemaphoreTake(touch_sem, portMAX_DELAY) == pdTRUE) { // 读取触摸状态 if (lcd.get_touch_state(&ts) && ts.touchDetected) { // 将第一个触点坐标发送到队列 TouchPoint_t point = {ts.touchX[0], ts.touchY[0]}; xQueueSend(touch_queue, &point, 0); } } } } // UI 主任务 void ui_task(void *pvParameters) { TouchPoint_t point; while (1) { // 从队列接收触摸点 if (xQueueReceive(touch_queue, &point, portMAX_DELAY) == pdTRUE) { // 判断是否在按钮区域内(例如:x:100-200, y:100-150) if (point.x >= 100 && point.x <= 200 && point.y >= 100 && point.y <= 150) { lcd.fill_rect(100, 100, 100, 50, LCD_COLOR_GREEN); lcd.draw_string(100, 100, "PRESSED!", LEFT_MODE); } else { lcd.fill_rect(100, 100, 100, 50, LCD_COLOR_GRAY); lcd.draw_string(100, 100, "BUTTON", LEFT_MODE); } } } } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); // 配置 PA15 为 EXTI 输入 // 创建信号量和队列 touch_sem = xSemaphoreCreateBinary(); touch_queue = xQueueCreate(10, sizeof(TouchPoint_t)); // 初始化 LCD 和触摸 lcd.init(); lcd.init_touch(); // 创建任务 xTaskCreate(touch_task, "Touch", 256, NULL, 2, NULL); xTaskCreate(ui_task, "UI", 512, NULL, 3, NULL); vTaskStartScheduler(); for(;;); }

4.3 与 HAL 库的协同工作

DISCOF469LCD 与 STM32 HAL 库完全兼容,其初始化依赖HAL_Init()SystemClock_Config()。在 STM32CubeMX 生成的工程中,只需:

  1. discof469lcd.cpp/h添加到工程;
  2. main.c#include "discof469lcd.h"
  3. 确保Drivers/BSP/STM32F469I-Discovery/路径已添加到编译器包含目录;
  4. main()中创建并初始化DISCOF469LCD实例。

关键 HAL 配置项(CubeMX 中需勾选):

  • RCC→ HSE ON, PLL config for 180MHz;
  • GPIO→ PA15 (TS_INT) as Input with Pull-up and EXTI;
  • I2C1→ Enabled for FT5336 (SCL: PB8, SDA: PB9);
  • LTDC,DMA2D,FMC→ Enabled and configured per BSP requirements.

5. 高级配置与调试技巧

5.1 帧缓冲区优化与双缓冲

DISCOF469LCD 默认使用 BSP 单缓冲(Single Buffering),即所有绘图操作直接写入 LTDC 当前显示的帧缓冲区,可能导致画面撕裂。为实现平滑动画,可启用双缓冲(Double Buffering):

  1. 修改 BSP 配置:在stm32f469i_discovery_lcd.c中,将LCD_FRAME_BUFFER定义为两个连续的 SDRAM 区域:
    #define LCD_FRAME_BUFFER_SIZE (480 * 272 * 2) // RGB565: 2 bytes/pixel uint16_t LCD_Fb[2][LCD_FRAME_BUFFER_SIZE]; // 两个缓冲区
  2. BSP_LCD_Init()中配置 LTDC 使用双缓冲:调用HAL_LTDC_SetAddress()切换活动层地址。
  3. DISCOF469LCD 扩展:添加swap_buffers()方法,在绘图完成后切换显示缓冲区。

性能权衡:双缓冲需额外 262KB SDRAM,但可彻底消除撕裂,适合视频播放或游戏。

5.2 常见问题诊断

现象可能原因解决方案
lcd.init()返回false1. SDRAM 未正确初始化;2. LTDC 时钟未使能;3. FMC 引脚配置错误检查MX_FMC_Init()是否被调用;用示波器测量LCD_BL_CTRL(PB0)是否输出 PWM;确认RCC->APB2ENRLTDCEN位为 1
屏幕全黑,但BSP_LCD_DisplayOn()已调用背光未开启DISCO-F469NI 的背光由 PB0 控制,需HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET)
触摸无响应1.TS_INT引脚未配置为 EXTI;2. I2C1 时钟未使能;3. FT5336 供电异常(3.3V)用万用表测 PB0(背光)和 PA15(中断)电压;用逻辑分析仪抓取 I2C 波形,确认地址0x38有 ACK
字符串显示乱码字体数据未正确链接确认fonts.c(含Font24)已加入工程;检查BSP_LCD_DisplayStringAt()调用的字体指针是否有效

5.3 内存布局与链接脚本适配

DISCO-F469NI 的 SDRAM(32MB)必须在链接脚本(STM32F469NIHx_FLASH.ld)中正确定义,以供 LTDC 使用:

/* 在 MEMORY 区域添加 */ MEMORY { RAM (xrw): ORIGIN = 0x20000000, LENGTH = 192K CCMRAM (rw): ORIGIN = 0x10000000, LENGTH = 64K SDRAM (xrw): ORIGIN = 0xC0000000, LENGTH = 32M /* 关键:SDRAM 起始地址 */ } /* 在 .bss 或自定义段中分配帧缓冲区 */ ._lcd_fb : { . = ALIGN(4); _s_lcd_fb = .; *(.lcd_fb) . = ALIGN(4); _e_lcd_fb = .; } > SDRAM

然后在 C 代码中将帧缓冲区放置于此段:

uint16_t __attribute__((section(".lcd_fb"))) lcd_frame_buffer[480 * 272];

此配置确保 LTDC 访问的内存位于高速 SDRAM,而非慢速内部 SRAM,是显示流畅性的基础保障。

6. 总结:从 BSP 到生产力的跨越

DISCOF469LCD 的价值不在于发明新的显示算法,而在于将 ST 官方 BSP 这一强大但低层次的工具集,转化为符合现代嵌入式 C++ 工程规范的生产力组件。它通过精巧的封装,解决了实际开发中反复出现的痛点:

  • 资源管理自动化:构造/析构自动完成初始化与反初始化,杜绝“忘记关闭外设”的低级错误;
  • 接口语义清晰化draw_string(..., CENTER_MODE)BSP_LCD_DisplayStringAt(x, y, ...)更直观地表达了开发者意图;
  • 错误处理显式化init()返回bool,强制调用者处理初始化失败场景;
  • 扩展性预留:触摸功能独立于显示,可单独启用/禁用,为后续添加手势识别(如滑动、缩放)留出接口;
  • 生态无缝集成:与 HAL、FreeRTOS、CMSIS-RTOS v2 完全兼容,可直接嵌入 CubeIDE 或 Keil 工程。

对于一个需要快速验证 GUI 概念的硬件工程师,DISCOF469LCD 意味着从阅读数十页 BSP 文档到lcd.draw_circle(100, 100, 20, RED)的跨越;对于一个构建工业 HMI 的嵌入式团队,它意味着一份经过充分测试、零运行时开销、且与 ST 官方支持完全对齐的显示子系统基础库。其存在本身,就是对“工程师时间是最昂贵资源”这一信条最务实的致敬。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 3:33:05

ROS导航实战:从Dijkstra到A*,全局路径规划算法对比与优化

1. ROS导航框架与路径规划基础 在机器人自主导航系统中&#xff0c;路径规划是核心功能之一。ROS&#xff08;Robot Operating System&#xff09;通过move_base包提供了完整的导航解决方案&#xff0c;其中全局路径规划负责计算从起点到目标点的最优路径。全局规划器需要依赖地…

作者头像 李华
网站建设 2026/4/16 1:46:06

FFmpeg 与 C++ 实战音视频处理:从环境搭建到流媒体解析

1. 为什么选择FFmpeg与C组合 音视频处理就像在数字厨房里烹饪一道复杂的菜肴&#xff0c;你需要得心应手的厨具和精准的烹饪技巧。FFmpeg就是这个厨房里的瑞士军刀&#xff0c;而C则是那位能够精准控制火候的大厨。这套组合在业内被称为"音视频处理的黄金搭档"&#…

作者头像 李华
网站建设 2026/4/11 0:53:28

如何永久保存微信聊天记忆:WeChatMsg数据导出与智能分析全攻略

如何永久保存微信聊天记忆&#xff1a;WeChatMsg数据导出与智能分析全攻略 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/…

作者头像 李华
网站建设 2026/4/11 0:52:00

从零到一:在麒麟V10桌面系统上部署Qt 5.12.3开发环境

1. 麒麟V10桌面系统安装准备 第一次接触国产操作系统可能会有点陌生&#xff0c;但别担心&#xff0c;跟着我的步骤来操作&#xff0c;保证你能顺利搞定。麒麟V10作为国产操作系统的代表&#xff0c;在政务、金融等领域应用越来越广泛。我去年接手一个政务项目迁移时&#xff0…

作者头像 李华