STM32+rt-thread使用MQTT協議連接騰訊物聯網平臺

STM32+rt-thread使用MQTT協議連接騰訊物聯網平臺

  • 一、騰訊云sdk下載
    • 1、進入騰訊物聯網平臺文件[點擊鏈接跳轉](https://cloud.tencent.com.cn/document/product/1081/48356)
    • 2、下載csdk
  • 二、移植騰訊云sdk
    • 1、將上面解壓的文件夾復制到自己工程目錄下
    • 2、文件添加到自己工程
  • 三、連接騰訊云

一、騰訊云sdk下載

1、進入騰訊物聯網平臺文件點擊鏈接跳轉

2、下載csdk

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

二、移植騰訊云sdk

1、將上面解壓的文件夾復制到自己工程目錄下

![在這里插入圖片描述](https://i-blog.csdnimg.cn/direct/fb4d5bdafaaa4bc397ada50c68528ac6.png

只復制圖中4個文件夾就可以。

2、文件添加到自己工程

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
注意這幾個文件夾:
在這里插入圖片描述
選rt-thread平臺就行,這都是人家寫好的,可以直接使用。

三、連接騰訊云

#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#include "qcloud_iot_export.h"
#include "qcloud_iot_import.h"
#include "service_mqtt.h"
#include "utils_getopt.h"
#include "lite-utils.h"#ifdef AUTH_MODE_CERT
static char sg_cert_file[PATH_MAX + 1];  // full path of device cert file
static char sg_key_file[PATH_MAX + 1];   // full path of device key file
#endiftypedef struct {bool     power_off;uint8_t  brightness;uint16_t color;char     device_name[MAX_SIZE_OF_DEVICE_NAME + 1];
} LedInfo;static DeviceInfo sg_devInfo;
static LedInfo    sg_led_info;// led attributes, corresponding to struct LedInfo
static char *sg_property_name[] = {"power_switch", "brightness", "color", "name"};// user's log print callback
static bool log_handler(const char *message)
{// return true if print successreturn false;
}// MQTT event callback
static void _mqtt_event_handler(void *pclient, void *handle_context, MQTTEventMsg *msg)
{MQTTMessage *mqtt_messge = (MQTTMessage *)msg->msg;uintptr_t    packet_id   = (uintptr_t)msg->msg;switch (msg->event_type) {case MQTT_EVENT_UNDEF:Log_i("undefined event occur.");break;case MQTT_EVENT_DISCONNECT:Log_i("MQTT disconnect.");break;case MQTT_EVENT_RECONNECT:Log_i("MQTT reconnect.");break;case MQTT_EVENT_PUBLISH_RECVEIVED:Log_i("topic message arrived but without any related handle: topic=%.*s, ""topic_msg=%.*s",mqtt_messge->topic_len, mqtt_messge->ptopic, mqtt_messge->payload_len, mqtt_messge->payload);break;case MQTT_EVENT_SUBCRIBE_SUCCESS:Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);break;case MQTT_EVENT_SUBCRIBE_TIMEOUT:Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);break;case MQTT_EVENT_SUBCRIBE_NACK:Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);break;case MQTT_EVENT_UNSUBCRIBE_SUCCESS:Log_i("unsubscribe success, packet-id=%u", (unsigned int)packet_id);break;case MQTT_EVENT_UNSUBCRIBE_TIMEOUT:Log_i("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id);break;case MQTT_EVENT_UNSUBCRIBE_NACK:Log_i("unsubscribe nack, packet-id=%u", (unsigned int)packet_id);break;case MQTT_EVENT_PUBLISH_SUCCESS:Log_i("publish success, packet-id=%u", (unsigned int)packet_id);break;case MQTT_EVENT_PUBLISH_TIMEOUT:Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);break;case MQTT_EVENT_PUBLISH_NACK:Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);break;default:Log_i("Should NOT arrive here.");break;}
}// Setup MQTT construct parameters
static int _setup_connect_init_params(MQTTInitParams *initParams)
{int ret;ret = HAL_GetDevInfo((void *)&sg_devInfo);if (QCLOUD_RET_SUCCESS != ret) {return ret;}initParams->region      = sg_devInfo.region;initParams->device_name = sg_devInfo.device_name;initParams->product_id  = sg_devInfo.product_id;#ifdef AUTH_MODE_CERTchar  certs_dir[PATH_MAX + 1] = "certs";char  current_path[PATH_MAX + 1];char *cwd = getcwd(current_path, sizeof(current_path));if (cwd == NULL) {Log_e("getcwd return NULL");return QCLOUD_ERR_FAILURE;}#ifdef WIN32sprintf(sg_cert_file, "%s\\%s\\%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);sprintf(sg_key_file, "%s\\%s\\%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
#elsesprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
#endifinitParams->cert_file = sg_cert_file;initParams->key_file  = sg_key_file;
#elseinitParams->device_secret = sg_devInfo.device_secret;
#endifinitParams->command_timeout        = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;initParams->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL;initParams->auto_connect_enable  = 1;initParams->event_handle.h_fp    = _mqtt_event_handler;initParams->event_handle.context = NULL;return QCLOUD_RET_SUCCESS;
}static void property_topic_publish(void *pClient, const char *message, int message_len)
{char topic[256] = {0};int  size;size = HAL_Snprintf(topic, 256, "$thing/up/property/%s/%s", sg_devInfo.product_id, sg_devInfo.device_name);if (size < 0 || size > 256 - 1) {Log_e("buf size < topic length!");return;}PublishParams pubParams = DEFAULT_PUB_PARAMS;pubParams.qos           = QOS0;pubParams.payload_len   = message_len;pubParams.payload       = (void *)message;IOT_MQTT_Publish(pClient, topic, &pubParams);
}static void property_get_status(void *pClient)
{char       message[256]        = {0};int        message_len         = 0;static int sg_get_status_index = 0;sg_get_status_index++;message_len = HAL_Snprintf(message, sizeof(message), "{\"method\":\"get_status\", \"clientToken\":\"%s-%d\"}",sg_devInfo.product_id, sg_get_status_index);property_topic_publish(pClient, message, message_len);
}static void property_report(void *pClient)
{char       message[256]    = {0};int        message_len     = 0;static int sg_report_index = 0;sg_report_index++;message_len = HAL_Snprintf(message, sizeof(message),"{\"method\":\"report\", \"clientToken\":\"%s-%d\", ""\"params\":{\"power_switch\":%d, \"color\":%d, \"brightness\":%d, \"name\":\"%s\"}}",sg_devInfo.product_id, sg_report_index, sg_led_info.power_off, sg_led_info.color,sg_led_info.brightness, sg_devInfo.device_name);// only change the brightness in the demosg_led_info.brightness %= 100;sg_led_info.brightness++;property_topic_publish(pClient, message, message_len);
}static void property_control_handle(void *pClient, const char *token, const char *control_data)
{char *params         = NULL;char *property_param = NULL;char  message[256]   = {0};int   message_len    = 0;params = LITE_json_value_of("params", (char *)control_data);if (NULL == params) {Log_e("Fail to parse params");return;}for (int i = 0; i < sizeof(sg_property_name) / sizeof(sg_property_name[0]); i++) {property_param = LITE_json_value_of(sg_property_name[i], params);if (NULL != property_param) {Log_i("\t%-16s = %-10s", sg_property_name[i], property_param);if (i == 1) {// only change the brightness in the demosg_led_info.brightness = atoi(property_param);}HAL_Free(property_param);}}// method: control_replymessage_len = HAL_Snprintf(message, sizeof(message),"{\"method\":\"control_reply\", \"code\":0, \"clientToken\":\"%s\"}", token);property_topic_publish(pClient, message, message_len);HAL_Free(params);
}static void property_get_status_reply_handle(const char *get_status_reply_data)
{char *data           = NULL;char *report         = NULL;char *property_param = NULL;data = LITE_json_value_of("data", (char *)get_status_reply_data);if (NULL == data) {Log_e("Fail to parse data");return;}report = LITE_json_value_of("reported", (char *)data);if (NULL == report) {Log_e("Fail to parse report");HAL_Free(data);return;}for (int i = 0; i < sizeof(sg_property_name) / sizeof(sg_property_name[0]); i++) {property_param = LITE_json_value_of(sg_property_name[i], report);if (NULL != property_param) {Log_i("\t%-16s = %-10s", sg_property_name[i], property_param);if (i == 1) {sg_led_info.brightness = atoi(property_param);}HAL_Free(property_param);}}HAL_Free(report);HAL_Free(data);
}static void property_report_reply_handle(const char *report_reply_data)
{char *status = NULL;status = LITE_json_value_of("status", (char *)report_reply_data);if (NULL == status) {Log_e("Fail to parse data");return;}Log_i("report reply status: %s", status);HAL_Free(status);
}void unbind_device_callback(void *pContext, const char *msg, uint32_t msgLen)
{Log_i("unbind device.");
}// callback when MQTT msg arrives
static void property_message_callback(void *pClient, MQTTMessage *message, void *userData)
{char  property_data_buf[QCLOUD_IOT_MQTT_RX_BUF_LEN + 1] = {0};int   property_data_len                                 = 0;char *type_str                                          = NULL;char *token_str                                         = NULL;if (message == NULL) {return;}Log_i("Receive Message With topicName:%.*s, payload:%.*s", (int)message->topic_len, message->ptopic,(int)message->payload_len, (char *)message->payload);property_data_len =sizeof(property_data_buf) > message->payload_len ? message->payload_len : QCLOUD_IOT_MQTT_RX_BUF_LEN;memcpy(property_data_buf, message->payload, property_data_len);type_str = LITE_json_value_of("method", property_data_buf);if (NULL == type_str) {Log_e("Fail to parse method");return;}token_str = LITE_json_value_of("clientToken", property_data_buf);if (NULL == type_str) {Log_e("Fail to parse token");HAL_Free(type_str);return;}if (0 == strncmp(type_str, "control", sizeof("control") - 1)) {// method: controlproperty_control_handle(pClient, token_str, property_data_buf);} else if (0 == strncmp(type_str, "get_status_reply", sizeof("get_status_reply") - 1)) {// method: get_status_replyproperty_get_status_reply_handle(property_data_buf);} else if (0 == strncmp(type_str, "report_reply", sizeof("report_reply") - 1)) {// method: report_replyproperty_report_reply_handle(property_data_buf);} else {// do nothing}HAL_Free(token_str);HAL_Free(type_str);
}// subscribe MQTT topic and wait for sub result
static int subscribe_property_topic_wait_result(void *client)
{char topic_name[128] = {0};int size = HAL_Snprintf(topic_name, sizeof(topic_name), "$thing/down/property/%s/%s", sg_devInfo.product_id,sg_devInfo.device_name);if (size < 0 || size > sizeof(topic_name) - 1) {Log_e("topic content length not enough! content size:%d  buf size:%d", size, (int)sizeof(topic_name));return QCLOUD_ERR_FAILURE;}SubscribeParams sub_params    = DEFAULT_SUB_PARAMS;sub_params.qos                = QOS0;sub_params.on_message_handler = property_message_callback;int rc = IOT_MQTT_Subscribe(client, topic_name, &sub_params);if (rc < 0) {Log_e("MQTT subscribe FAILED: %d", rc);return rc;}int wait_cnt = 10;while (!IOT_MQTT_IsSubReady(client, topic_name) && (wait_cnt > 0)) {// wait for subscription resultrc = IOT_MQTT_Yield(client, 1000);if (rc) {Log_e("MQTT error: %d", rc);return rc;}wait_cnt--;}if (wait_cnt > 0) {return QCLOUD_RET_SUCCESS;} else {Log_e("wait for subscribe result timeout!");return QCLOUD_ERR_FAILURE;}
}#ifdef LOG_UPLOAD
// init log upload module
static int _init_log_upload(MQTTInitParams *init_params)
{LogUploadInitParams log_init_params;memset(&log_init_params, 0, sizeof(LogUploadInitParams));log_init_params.region      = init_params->region;log_init_params.product_id  = init_params->product_id;log_init_params.device_name = init_params->device_name;
#ifdef AUTH_MODE_CERTlog_init_params.sign_key = init_params->cert_file;
#elselog_init_params.sign_key = init_params->device_secret;
#endif#if defined(__linux__) || defined(WIN32)log_init_params.read_func     = HAL_Log_Read;log_init_params.save_func     = HAL_Log_Save;log_init_params.del_func      = HAL_Log_Del;log_init_params.get_size_func = HAL_Log_Get_Size;
#endifreturn IOT_Log_Init_Uploader(&log_init_params);
}#endifstatic bool sg_loop_test = false;
static int  parse_arguments(int argc, char **argv)
{int c;while ((c = utils_getopt(argc, argv, "c:l")) != EOF) switch (c) {case 'c':if (HAL_SetDevInfoFile(utils_optarg))return -1;break;case 'l':sg_loop_test = true;break;default:HAL_Printf("usage: %s [options]\n""  [-c <config file for DeviceInfo>] \n""  [-l ] loop test or not\n",argv[0]);return -1;}return 0;
}int main(int argc, char **argv)
{int rc;// init log levelIOT_Log_Set_Level(eLOG_DEBUG);IOT_Log_Set_MessageHandler(log_handler);// parse arguments for device info file and loop test;rc = parse_arguments(argc, argv);if (rc != QCLOUD_RET_SUCCESS) {Log_e("parse arguments error, rc = %d", rc);return rc;}// init connectionMQTTInitParams init_params = DEFAULT_MQTTINIT_PARAMS;rc                         = _setup_connect_init_params(&init_params);if (rc != QCLOUD_RET_SUCCESS) {Log_e("init params error, rc = %d", rc);return rc;}#ifdef LOG_UPLOAD// _init_log_upload should be done after _setup_connect_init_params and before IOT_MQTT_Constructrc = _init_log_upload(&init_params);if (rc != QCLOUD_RET_SUCCESS)Log_e("init log upload error, rc = %d", rc);
#endif// create MQTT client and connect with servervoid *client = IOT_MQTT_Construct(&init_params);if (client != NULL) {Log_i("Cloud Device Construct Success");} else {rc = IOT_MQTT_GetErrCode();Log_e("MQTT Construct failed, rc = %d", rc);return QCLOUD_ERR_FAILURE;}#ifdef SYSTEM_COMMlong time = 0;// get system timestamp from serverrc = IOT_Get_Sys_Resource(client, eRESOURCE_TIME, &sg_devInfo, &time);if (QCLOUD_RET_SUCCESS == rc) {Log_i("system time is %ld", time);} else {Log_e("get system time failed!");}
#endif// subscribe normal topics hererc = subscribe_property_topic_wait_result(client);if (rc < 0) {Log_e("Client Subscribe Topic Failed: %d", rc);return rc;}// when platform unbind this device. the callback function will runIOT_Unbind_Device_ByCloud(client, unbind_device_callback, NULL);// method: get_statusproperty_get_status(client);do {rc = IOT_MQTT_Yield(client, 500);if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT) {HAL_SleepMs(1000);continue;} else if (rc != QCLOUD_RET_SUCCESS && rc != QCLOUD_RET_MQTT_RECONNECTED) {if (rc == QCLOUD_ERR_MQTT_RECONNECT_TIMEOUT) {Log_e("exit. mqtt reconnect timeout! Please check the network connection, or try to increase ""MAX_RECONNECT_WAIT_INTERVAL(%d)",MAX_RECONNECT_WAIT_INTERVAL);} else {Log_e("exit with error: %d", rc);}break;}if (sg_loop_test)HAL_SleepMs(1000);// method: reportproperty_report(client);} while (sg_loop_test);rc = IOT_Unbind_Device_Request(client, 5000);if (rc != QCLOUD_RET_SUCCESS) {Log_e("unbind device request error.");}rc = IOT_MQTT_Destroy(&client);IOT_Log_Upload(true);#ifdef LOG_UPLOADIOT_Log_Fini_Uploader();
#endifreturn rc;
}

注意,記得將HAL_Device_rtthread.c文件中的參數替換為自己的:
在這里插入圖片描述
對應參數在騰訊云設備管理中查看:
在這里插入圖片描述
SDK文章頂部下載。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/906967.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906967.shtml
英文地址,請注明出處:http://en.pswp.cn/news/906967.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【MySQL成神之路】MySQL函數總結

以下是MySQL函數的全面總結&#xff0c;包含概念說明和代碼示例&#xff1a; 一、MySQL函數分類 1. 字符串函數 -- CONCAT&#xff1a;連接字符串 SELECT CONCAT(Hello, , World); -- 輸出 Hello World -- SUBSTRING&#xff1a;截取子串 SELECT SUBSTRING(MySQL, 2, 3…

JavaScript 異步編程、對象/數組操作

異步編程 JavaScript 是單線程語言&#xff0c;通過事件循環機制處理異步操作。任務分為兩種&#xff1a; 宏任務(Macrotask): script整體代碼、setTimeout&#xff08;時間結束執行&#xff09;、setInterval&#xff08;間隔執行&#xff09;、I/O、UI渲染 微任務(Microtas…

中小制造企業網絡安全防護指南

考慮到文章內容較長&#xff0c;簡要內容圖片在文檔末尾&#xff0c;請直接翻閱到底部查看 引言&#xff1a;中小制造企業面臨的獨特網絡安全挑戰 中小制造企業 (SME) 在當今數字化浪潮中扮演著至關重要的角色&#xff0c;然而&#xff0c;伴隨技術進步而來的是日益嚴峻且獨特…

es學習小結

1.?客戶端類型? ?推薦場景? ?版本兼容性? Elasticsearch Java API Client 新項目、ES 8.x集群 8.x及以上 Spring Data Elasticsearch Spring生態項目、簡化ORM操作 ES 7.x-8.x&#xff08;需版本匹配&#xff09; Low-Level REST Client 需要底層HTTP控制、兼容多版本ES …

Axure項目實戰:智慧運輸平臺后臺管理端-訂單管理2(多級交互)

親愛的小伙伴,在您瀏覽之前,煩請關注一下,在此深表感謝!如有幫助請訂閱專欄! Axure產品經理精品視頻課已登錄CSDN可點擊學習https://edu.csdn.net/course/detail/40420 課程主題:訂單管理2 主要內容:中繼器篩選、表單跟隨菜單拖動、審批數據互通等 應用場景:訂單管理…

2025年——ComfyUI_連接HuggingFace及更改緩存路徑

本篇分享在 ComfyUI 中連接 huggingface 以及更改模型緩存路徑。 我們在使用 ComfyUI 的一些插件時&#xff0c;有些必要模型只能通過連接 huggingface 來緩存才能讓流程得以進行。但目前在上網不科學的情況下是無法打開 huggingface 網站的&#xff0c;好在國內有其鏡像網站&a…

wx.getPrivacySetting接口needAuthorization一直返回false

我們在開發小程序的隱私協議授權時往往會使用到wx.getPrivacySetting接口&#xff0c;當返回的needAuthorization為true時候提示我們需要去授權&#xff0c;但你們有沒有遇到過needAuthorization一直為false的情況呢&#xff0c;下面是最常見的三個解決方法&#xff0c;都完善了…

旅游信息檢索

旅游信息檢索 旅游信息檢索是系統中實現數據獲取和處理的關鍵環節&#xff0c;負責根據用戶輸入的目的地城市和出游天數&#xff0c;動態獲取并生成高質量的旅游數據。 模塊的工作流程分為以下幾個階段&#xff1a;首先&#xff0c;對用戶輸入的信息進行標準化處理&#xff0…

機器學習筆記【Week2】

一、多變量線性回歸&#xff08;Multivariate Linear Regression&#xff09; 為什么需要多變量&#xff1f; 現實問題中&#xff0c;一個目標可能受多個因素影響&#xff0c;比如預測房價時&#xff1a; x 1 x_1 x1?&#xff1a;面積 x 2 x_2 x2?&#xff1a;臥室數量 x 3…

Axure 基本用法學習筆記

一、元件操作基礎 1. 可見性控制 隱藏/顯示&#xff1a;可以設置元件的可見性&#xff0c;使元件在特定條件下隱藏或可見 應用場景&#xff1a;創建動態交互效果&#xff0c;如點擊按鈕顯示隱藏內容 2. 層級管理 層級概念&#xff1a;元件有上下層關系&#xff0c;上層元件…

aws平臺s3存儲桶夸域問題處理

當我們收到開發反饋s3存在跨域問題 解決步驟&#xff1a; 配置 S3 存儲桶的 CORS 設置&#xff1a; 登錄到 AWS 管理控制臺。轉到 S3 服務。選擇你存儲文件的 存儲桶。點擊 權限 標簽頁。在 跨域資源共享&#xff08;CORS&#xff09;配置 部分&#xff0c;點擊 編輯。 登陸…

【后端高階面經:微服務篇】7、1秒響應保障:超時控制如何成為高并發系統的“救火隊長”?

一、全鏈路超時建模:從用戶需求到系統分解 1.1 端到端時間預算分配 黃金公式: 用戶期望響應時間 = 網絡傳輸時間 + 服務處理時間 + 下游調用時間 + 緩沖時間典型分配策略(以1秒目標為例): 環節時間預算優化目標客戶端渲染100ms骨架屏(Skeleton)預渲染邊緣節點(CDN)…

前端遇到高并發如何解決重復請求

在前端開發中遇到高并發場景時&#xff0c;若不加控制容易出現重復請求&#xff0c;這可能導致接口壓力增加、數據異常、用戶體驗變差等問題。以下是前端防止/解決重復請求的常見方法&#xff0c;按不同場景歸類總結&#xff1a; &#x1f31f; 一、常見重復請求場景 用戶頻繁點…

老牌協議再升級,Ethernet IP轉Modbus TCP網關橋接精準灌裝系統

對于消費品包裝制造商而言&#xff0c;灌裝機是最關鍵且昂貴的設備之一。然而&#xff0c;許多公司卻難以應對生產過程中的灌裝波動&#xff0c;從而造成嚴重的財務和生產后果。 在本次網絡研討會中&#xff0c;我們將探討穩聯技術的ethernet ip轉modbus tcp&#xff08;WL-ABC…

骰子游戲(2023睿抗省賽)

骰子游戲 題目描述: 在某個游戲中有一個骰子游戲。 在游戲中&#xff0c;你需要投擲 5 個標準六面骰子&#xff08;骰子為一個正方體&#xff0c;6個面上分別有 1、2、3、4、5、6中的一個數字&#xff0c;骰子的質量均勻&#xff09;&#xff0c;投出的點數根據組合會獲得一…

CMake跨平臺編譯生成:從理論到實戰

一、引言 在當今軟件開發中&#xff0c;跨平臺開發已成為常態。無論是需要在Windows、Linux、macOS等多操作系統上運行&#xff0c;還是在不同的硬件架構&#xff08;如x86、ARM等&#xff09;間部署&#xff0c;跨平臺編譯生成都是一個無法回避的關鍵問題。CMake&#xff0c;…

Python經典算法實戰

在編程的世界里&#xff0c;算法是解決問題的靈魂&#xff0c;而Python以其簡潔優雅的語法成為實現算法的理想語言。無論你是初學者還是有一定經驗的開發者&#xff0c;《Python經典算法實戰》都能帶你深入算法的殿堂&#xff0c;從理論到實踐&#xff0c;一步步構建起扎實的編…

QT的自定義控件

1.比如對label控件進行提升為QPaintPointLabel類&#xff0c;基類選擇QLabel&#xff0c;頭文件建議加上相對路徑&#xff0c;有時候VS識別不出來直接的頭文件&#xff0c;在提升的類中重寫pointEvent&#xff08;&#xff09;函數。

flutter 常用組件詳細介紹、屏幕適配方案

一、常用組件 1.基礎組件 組件說明示例Text顯示文本Text(‘Hello Flutter’, style: TextStyle(fontSize: 20))Image顯示圖片Image.network(‘https://example.com/image.jpg’)Icon顯示圖標Icon(Icons.home, size: 30, color: Colors.blue)RaisedButton / ElevatedButton按鈕…

leetcode 17. Letter Combinations of a Phone Number

題目描述 17. Letter Combinations of a Phone Number 代碼&#xff1a; class Solution {string table[10] {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz&qu…