C++Qt学习笔记——实现一个串口通信界面
C++Qt学习笔记——实现一个串口通信界面
- 一.界面
- 二、项目结构
- 三、头文件
- 1. 文件头部
- 2. 类定义
- 3. 构造函数和析构函数
- 4. 成员函数
- 5. 成员变量
- 四、代码解析
- `ReceiveAeraInit` 函数解析
- SerialHelper 构造函数解析
- 1. 为什么有两个 `SerialHelper`?
- 2. 为什么用 `::` 和 `:`?
- 1. `this` 的作用
- 2. `connect` 的作用
- 1. 接收区初始化
- 2. 发送区初始化
- 3. 串口配置初始化
- 4. 串口连接与断开
- 5. 串口通信实现
- 6. 动态更新串口列表
- 7. 主窗口初始化
参考以下视频
一.界面

二、项目结构
本项目包含以下功能模块:
- 接收区初始化:用于显示接收到的数据。
- 发送区初始化:用于输入并发送数据。
- 串口配置初始化:用于配置串口参数(如波特率、数据位等)。
- 串口操作:连接和断开串口,以及数据的发送和接收。
- 动态更新串口列表:定时扫描系统中的串口并更新下拉菜单。
三、头文件
#pragma once#include <QtWidgets/QMainWindow>
#include "ui_SerialHelper.h"
#include <QPlainTextEdit>
#include <QPushButton>
#include <QComboBox>
#include <QLabel>
#include <QDebug>
#include <QSerialPort>
#include<QSerialPortInfo>
#include<QMessageBox>
class SerialHelper : public QMainWindow
{Q_OBJECTpublic:SerialHelper(QWidget *parent = nullptr);~SerialHelper();void ReceiveAeraInit(void);void SendAeraInit(void);void SetupInit(void);void BeginUSART(void);void USART(void);void timerEvent(QTimerEvent*);
private:QPlainTextEdit* sendAera;QPlainTextEdit* receiveAera;QPushButton* sendButton;QPushButton* startUSART;QPushButton* endUSART;QComboBox* port;QComboBox* baudRate;QComboBox* dataSize;QComboBox* stopSize;QComboBox* check;QComboBox* receiveMode;QComboBox* sendMode;QSerialPort* serialPort;QVector<QString> ports;
};
这段代码是一个基于Qt的串口助手工具的类定义,它声明了SerialHelper类及其成员变量和成员函数。以下是详细解析:
1. 文件头部
#pragma once
#pragma once 是一个预处理器指令,用于防止头文件的重复包含。它确保该头文件在编译过程中只被包含一次,从而避免重复定义问题。
#include <QtWidgets/QMainWindow>
#include "ui_SerialHelper.h"
#include <QPlainTextEdit>
#include <QPushButton>
#include <QComboBox>
#include <QLabel>
#include <QDebug>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QMessageBox>
这些是必要的头文件:
QtWidgets/QMainWindow:QMainWindow是Qt提供的一个主窗口类,SerialHelper类继承自它。ui_SerialHelper.h:这是Qt Designer生成的UI类的头文件,通常包含窗口的界面布局。- 其他头文件:提供了Qt中各种控件和功能的类,如
QPlainTextEdit(多行文本编辑框)、QPushButton(按钮)、QComboBox(下拉菜单)、QSerialPort(串口通信类)等。
2. 类定义
class SerialHelper : public QMainWindow
{Q_OBJECT
class SerialHelper:定义了一个名为SerialHelper的类。: public QMainWindow:表示SerialHelper类继承自QMainWindow,即SerialHelper是一个主窗口类。Q_OBJECT:这是一个宏,用于Qt的信号和槽机制,它使得类可以使用信号和槽功能。
3. 构造函数和析构函数
public:SerialHelper(QWidget *parent = nullptr);~SerialHelper();
SerialHelper(QWidget *parent = nullptr):构造函数,用于初始化SerialHelper对象。QWidget *parent是一个指向父窗口的指针,默认值为nullptr,表示该窗口没有父窗口。~SerialHelper():析构函数,用于清理SerialHelper对象占用的资源。
4. 成员函数
void ReceiveAeraInit(void);void SendAeraInit(void);void SetupInit(void);void BeginUSART(void);void USART(void);void timerEvent(QTimerEvent*);
ReceiveAeraInit(void):初始化接收区域的函数。SendAeraInit(void):初始化发送区域的函数。SetupInit(void):初始化串口设置区域的函数。BeginUSART(void):初始化串口连接和断开按钮的函数。USART(void):配置串口参数并打开串口的函数。timerEvent(QTimerEvent*):定时器事件处理函数,用于定时更新串口列表。
5. 成员变量
private:QPlainTextEdit* sendAera;QPlainTextEdit* receiveAera;QPushButton* sendButton;QPushButton* startUSART;QPushButton* endUSART;QComboBox* port;QComboBox* baudRate;QComboBox* dataSize;QComboBox* stopSize;QComboBox* check;QComboBox* receiveMode;QComboBox* sendMode;QSerialPort* serialPort;QVector<QString> ports;
QPlainTextEdit* sendAera:发送区域的文本编辑框。QPlainTextEdit* receiveAera:接收区域的文本编辑框。QPushButton* sendButton:发送按钮。QPushButton* startUSART:串口连接按钮。QPushButton* endUSART:串口断开按钮。QComboBox* port:串口号下拉菜单。QComboBox* baudRate:波特率下拉菜单。QComboBox* dataSize:数据位下拉菜单。QComboBox* stopSize:停止位下拉菜单。QComboBox* check:校验位下拉菜单。QComboBox* receiveMode:接收模式下拉菜单。QComboBox* sendMode:发送模式下拉菜单。QSerialPort* serialPort:串口对象,用于串口通信。QVector<QString> ports:存储当前系统中可用串口的名称。
四、代码解析
ReceiveAeraInit 函数解析
void SerialHelper::ReceiveAeraInit(void) {receiveAera = new QPlainTextEdit(this); // 创建一个 QPlainTextEdit 对象,并将其存储在 receiveAera 成员变量中receiveAera->setFixedSize(800, 400); // 设置接收区的固定大小为 800x400 像素receiveAera->move(30, 20); // 将接收区移动到窗口的 (30, 20) 位置receiveAera->setReadOnly(true); // 设置接收区为只读模式QPushButton* clearReceive = new QPushButton(QString::fromLocal8Bit("清空接收区"), this); // 创建“清空接收区”按钮clearReceive->setFixedSize(150, 50); // 设置按钮的固定大小为 150x50 像素clearReceive->move(680, 430); // 将按钮移动到窗口的 (680, 430) 位置connect(clearReceive, &QPushButton::clicked, [&]() { // 将按钮的点击事件连接到槽函数receiveAera->clear(); // 清空接收区的内容});
}
SerialHelper 构造函数解析
SerialHelper::SerialHelper(QWidget *parent): QMainWindow(parent) // 继承自QMainWindow
{this->setFixedSize(1200, 750); // 设置窗口的固定大小为1200x750像素this->setWindowTitle(QString::fromLocal8Bit("串口助手")); // 设置窗口标题为“串口助手”
}
1. 为什么有两个 SerialHelper?
- 第一个
SerialHelper:这是类名,表示构造函数所属的类。 - 第二个
SerialHelper:这是构造函数的名称,表示正在定义的函数。在C++中,构造函数的名称必须与类名相同。
2. 为什么用 :: 和 :?
-
::(作用域解析运算符):- 用于指定某个成员(如函数或变量)属于哪个类。
- 在
SerialHelper::SerialHelper中,::表示SerialHelper构造函数属于SerialHelper类。
-
:(初始化列表符号):- 用于在构造函数中初始化类的成员变量或调用基类的构造函数。
- 在
: QMainWindow(parent)中,:表示初始化列表的开始,QMainWindow(parent)是调用基类QMainWindow的构造函数。
1. this 的作用
- 在
new QPlainTextEdit(this)中,this表示当前SerialHelper对象。 - 作为父窗口传递给
QPlainTextEdit,表示QPlainTextEdit是SerialHelper窗口的一部分。
2. connect 的作用
connect(clearReceive, &QPushButton::clicked, [&]() { receiveAera->clear(); });
-
connect:- 单词解释:
connect是 Qt 框架中的一个函数,用于连接信号和槽。 - 作用:在这里,
connect将按钮的clicked信号连接到一个槽函数。
- 单词解释:
-
clearReceive:- 单词解释:这是按钮对象的变量名。
- 作用:表示“清空接收区”按钮。
-
&QPushButton::clicked:- 符号解释:
&是 C++ 中的取地址运算符。 - 作用:在这里,
&QPushButton::clicked表示QPushButton类的clicked信号。
- 符号解释:
-
[&]():- 单词解释:
[&]是 C++11 中的 lambda 表达式捕获列表,表示捕获当前作用域的所有变量。 - 作用:在这里,
[&]表示捕获receiveAera对象,以便在 lambda 表达式中使用。
- 单词解释:
-
receiveAera->clear();:- 单词解释:
clear是QPlainTextEdit类的一个方法,用于清空文本内容。 - 作用:在这里,
clear方法用于清空接收区域的内容。
- 单词解释:
:::用于指定成员属于哪个类。::用于初始化类的成员变量或调用基类的构造函数。this:表示当前对象,用于将子控件添加到父窗口。connect:用于连接信号和槽,实现事件驱动编程。lambda表达式:用于简化代码,捕获当前作用域的变量。
1. 接收区初始化
接收区是一个只读的文本框,用于显示从串口接收到的数据。我们还添加了一个按钮用于清空接收区内容。
void SerialHelper::ReceiveAeraInit(void) {receiveAera = new QPlainTextEdit(this); // 创建一个文本编辑框receiveAera->setFixedSize(800, 400); // 设置固定大小receiveAera->move(30, 20); // 设置位置receiveAera->setReadOnly(true); // 设置为只读QPushButton* clearReceive = new QPushButton(QString::fromLocal8Bit("清空接收区"), this); // 创建清空按钮clearReceive->setFixedSize(150, 50); // 设置按钮大小clearReceive->move(680, 430); // 设置按钮位置connect(clearReceive, &QPushButton::clicked, [&]() { // 绑定按钮点击事件receiveAera->clear(); // 清空接收区});
}
2. 发送区初始化
发送区是一个可编辑的文本框,用于输入要发送的数据。我们还添加了一个发送按钮和一个清空发送区的按钮。
void SerialHelper::SendAeraInit(void) {sendAera = new QPlainTextEdit(this); // 创建发送区文本框sendAera->setFixedSize(800, 100); // 设置大小sendAera->move(30, 500); // 设置位置sendButton = new QPushButton(QString::fromLocal8Bit("发送"), this); // 创建发送按钮sendButton->setFixedSize(150, 50); // 设置按钮大小sendButton->move(500, 630); // 设置按钮位置sendButton->setDisabled(true); // 初始状态禁用connect(sendButton, &QPushButton::clicked, [&]() { // 绑定发送按钮点击事件QString data = sendAera->toPlainText(); // 获取发送区内容if (sendMode->currentText() == "HEX") { // 如果发送模式为HEXQByteArray arr;for (int i = 0; i < data.size(); ++i) {if (data[i] == ' ') continue; // 跳过空格int num = data.mid(i, 2).toUInt(nullptr, 16); // 将两个字符转换为一个字节++i;arr.append(num);}serialPort->write(arr); // 写入串口} else {serialPort->write(data.toLocal8Bit().data()); // 文本模式直接发送}});QPushButton* clearSend = new QPushButton(QString::fromLocal8Bit("清空发送区"), this); // 创建清空发送区按钮clearSend->setFixedSize(150, 50); // 设置按钮大小clearSend->move(680, 630); // 设置按钮位置connect(clearSend, &QPushButton::clicked, [&]() { // 绑定按钮点击事件sendAera->clear(); // 清空发送区});
}
3. 串口配置初始化
串口配置部分包括串口号、波特率、数据位、停止位、校验位等参数的设置。
void SerialHelper::SetupInit(void) {port = new QComboBox(this); // 创建串口号下拉菜单baudRate = new QComboBox(this); // 创建波特率下拉菜单dataSize = new QComboBox(this); // 创建数据位下拉菜单stopSize = new QComboBox(this); // 创建停止位下拉菜单check = new QComboBox(this); // 创建校验位下拉菜单receiveMode = new QComboBox(this); // 创建接收模式下拉菜单sendMode = new QComboBox(this); // 创建发送模式下拉菜单// 添加波特率选项baudRate->addItem("4800");baudRate->addItem("9600");baudRate->addItem("19200");baudRate->addItem("38400");baudRate->addItem("115200");// 添加数据位选项dataSize->addItem("8");// 添加停止位选项stopSize->addItem("1");stopSize->addItem("1.5");stopSize->addItem("2");// 添加校验位选项check->addItem(QString::fromLocal8Bit("无校验"));check->addItem(QString::fromLocal8Bit("奇校验"));check->addItem(QString::fromLocal8Bit("偶校验"));// 添加接收和发送模式选项receiveMode->addItem("HEX");receiveMode->addItem(QString::fromLocal8Bit("文本"));sendMode->addItem("HEX");sendMode->addItem(QString::fromLocal8Bit("文本"));// 创建标签并设置位置QLabel* portLabel = new QLabel(QString::fromLocal8Bit("串口号"), this);QLabel* baudLabel = new QLabel(QString::fromLocal8Bit("波特率"), this);QLabel* dataLabel = new QLabel(QString::fromLocal8Bit("数据位"), this);QLabel* stopLabel = new QLabel(QString::fromLocal8Bit("停止位"), this);QLabel* checkLabel = new QLabel(QString::fromLocal8Bit("校验位"), this);QLabel* receiveLabel = new QLabel(QString::fromLocal8Bit("接收格式"), this);QLabel* sendLabel = new QLabel(QString::fromLocal8Bit("发送格式"), this);// 设置下拉菜单和标签的位置QVector<QComboBox*> setups = {port, baudRate, dataSize, stopSize, check, receiveMode, sendMode};QVector<QLabel*> labels = {portLabel, baudLabel, dataLabel, stopLabel, checkLabel, receiveLabel, sendLabel};for (int i = 0; i < setups.size(); i++) {setups[i]->setFixedSize(200, 50);setups[i]->move(850, 20 + 80 * i);labels[i]->move(1080, 25 + i * 80);}
}
4. 串口连接与断开
串口连接和断开功能通过两个按钮实现。连接按钮用于打开串口,断开按钮用于关闭串口。
void SerialHelper::BeginUSART(void) {startUSART = new QPushButton(QString::fromLocal8Bit("串口连接"), this); // 创建连接按钮endUSART = new QPushButton(QString::fromLocal8Bit("串口断开"), this); // 创建断开按钮startUSART->setFixedSize(150, 50);endUSART->setFixedSize(150, 50);startUSART->move(1000, 630);endUSART->move(840, 630);endUSART->setDisabled(true); // 初始状态禁用断开按钮// 绑定断开按钮点击事件connect(endUSART, &QPushButton::clicked, [&]() {sendButton->setDisabled(true); // 禁用发送按钮startUSART->setDisabled(false); // 启用连接按钮endUSART->setDisabled(true); // 禁用断开按钮serialPort->close(); // 关闭串口});// 绑定连接按钮点击事件connect(startUSART, &QPushButton::clicked, [&]() {QString port1 = port->currentText(); // 获取串口号QString baud = baudRate->currentText(); // 获取波特率QString data = dataSize->currentText(); // 获取数据位QString stop = stopSize->currentText(); // 获取停止位QString ch = check->currentText(); // 获取校验位QString receive = receiveMode->currentText(); // 获取接收模式QString send = sendMode->currentText(); // 获取发送模式if (port->currentText() != "") {startUSART->setDisabled(true); // 禁用连接按钮endUSART->setDisabled(false); // 启用断开按钮sendButton->setDisabled(false); // 启用发送按钮USART(); // 调用USART函数连接串口} else {QMessageBox::critical(this, QString::fromLocal8Bit("串口打开失败"), QString::fromLocal8Bit("请确认串口是否正确连接"));}});
}
5. 串口通信实现
USART函数用于配置串口参数并打开串口。一旦串口打开成功,我们通过QSerialPort::readyRead信号接收数据,并将其显示在接收区。
void SerialHelper::USART(void) {QSerialPort::BaudRate Baud; // 波特率QSerialPort::DataBits Data; // 数据位QSerialPort::StopBits Stop; // 停止位QSerialPort::Parity Check; // 校验位QString por = port->currentText(); // 获取串口号QString baud = baudRate->currentText(); // 获取波特率QString data = dataSize->currentText(); // 获取数据位QString stop = stopSize->currentText(); // 获取停止位QString ch = check->currentText(); // 获取校验位// 根据下拉菜单选择配置串口参数if (baud == "4800") Baud = QSerialPort::Baud4800;else if (baud == "9600") Baud = QSerialPort::Baud9600;else if (baud == "19200") Baud = QSerialPort::Baud19200;else if (baud == "38400") Baud = QSerialPort::Baud38400;else if (baud == "115200") Baud = QSerialPort::Baud115200;if (data == "8") Data = QSerialPort::Data8;if (stop == "1") Stop = QSerialPort::OneStop;else if (stop == "1.5") Stop = QSerialPort::OneAndHalfStop;else if (stop == "2") Stop = QSerialPort::TwoStop;if (ch == QString::fromLocal8Bit("无校验")) Check = QSerialPort::NoParity;else if (ch == QString::fromLocal8Bit("奇校验")) Check = QSerialPort::OddParity;else if (ch == QString::fromLocal8Bit("偶校验")) Check = QSerialPort::EvenParity;serialPort = new QSerialPort(this); // 创建串口对象serialPort->setBaudRate(Baud); // 设置波特率serialPort->setPortName(por); // 设置串口号serialPort->setDataBits(Data); // 设置数据位serialPort->setParity(Check); // 设置校验位serialPort->setStopBits(Stop); // 设置停止位// 打开串口if (serialPort->open(QSerialPort::ReadWrite)) {// 绑定数据接收信号connect(serialPort, &QSerialPort::readyRead, [&]() {QByteArray data = serialPort->readAll(); // 读取数据if (receiveMode->currentText() == "HEX") { // 如果接收模式为HEXQString hex = data.toHex(' '); // 转换为十六进制字符串receiveAera->appendPlainText(hex); // 显示在接收区} else { // 如果接收模式为文本QString str = QString(data); // 转换为文本receiveAera->appendPlainText(str); // 显示在接收区}});} else {QMessageBox::critical(this, QString::fromLocal8Bit("串口打开失败"), QString::fromLocal8Bit("请确认串口是否正确连接"));}
}
6. 动态更新串口列表
通过timerEvent函数,我们定时扫描系统中的串口,并更新下拉菜单中的串口列表。
void SerialHelper::timerEvent(QTimerEvent* e) {QVector<QString> temp; // 临时存储当前可用串口for (const QSerialPortInfo& info : QSerialPortInfo::availablePorts()) {temp.push_back(info.portName()); // 获取所有可用串口的名称}qSort(temp.begin(), temp.end()); // 对串口名称排序if (temp != ports) { // 如果当前串口列表与之前不同this->port->clear(); // 清空下拉菜单this->ports = temp; // 更新串口列表for (auto& a : ports) {this->port->addItem(a); // 将新串口名称添加到下拉菜单}}
}
7. 主窗口初始化
在构造函数中,我们初始化窗口大小、标题,并调用上述初始化函数。
SerialHelper::SerialHelper(QWidget* parent) : QMainWindow(parent) {this->setFixedSize(1200, 750); // 设置窗口大小this->setWindowTitle(QString::fromLocal8Bit("串口助手")); // 设置窗口标题ReceiveAeraInit(); // 初始化接收区SendAeraInit(); // 初始化发送区SetupInit(); // 初始化串口配置BeginUSART(); // 初始化串口连接按钮this->startTimer(1000); // 启动定时器,每秒更新串口列表
}
相关文章:
C++Qt学习笔记——实现一个串口通信界面
CQt学习笔记——实现一个串口通信界面 一.界面二、项目结构三、头文件1. 文件头部2. 类定义3. 构造函数和析构函数4. 成员函数5. 成员变量 四、代码解析ReceiveAeraInit 函数解析SerialHelper 构造函数解析1. 为什么有两个 SerialHelper?2. 为什么用 :: 和 :&#x…...
Word(2010)排版技巧
设置标题样式 选择需要设置的标题 如下图所示。选择文字后,点击对应的样式即可设置。 设置标题格式 设置字体格式 设置段落格式 显示所有样式 标题样式展示 建议 建议新建一个正文样式,可以命名为正文1,因为所有的样式参考的“样式基准…...
一.Vue中的条件渲染
1.在<head>中引用 <script src"https://unpkg.com/vue3/dist/vue.global.js"></script> 2.在<body>中写入 <div id"app"><p><a v-if "user.usernameadmin"href"#">编辑</a><a …...
IO进程 day05
IO进程 day05 9. 进程9. 9. 守护进程守护进程的特点守护进程创建步骤 10. 线程10.1. 线程的概念10.2. 进程和线程的区别10.2. 线程资源10.3. 线程的函数接口1. pthread_create-创建线程线程函数和普通函数的区别 2. pthread_exit3.线程资源回收函数join和detach的区别 获取线程…...
【HeadFirst系列之HeadFirstJava】第6天之认识Java的API:解锁高效开发的钥匙
认识Java的API:解锁高效开发的钥匙 在《Head First Java》的第六章节中,作者深入探讨了Java的API(Application Programming Interface),并强调了它在Java开发中的重要性。Java API 是Java开发工具包(JDK&a…...
4 - AXI GPIO按键控制LED实验
文章目录 1 实验任务2 系统框图3 软件设计 1 实验任务 本实验任务是通过调用PL端AXI GPIO IP核,使用中断机制,实现PL端按键控制 PS端LED的功能。 2 系统框图 3 软件设计 注意事项: AXI GPIO IP核是双沿触发中断,不可设置&…...
题海拾贝:扫雷
Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路! 我的博客:<但凡. 我的专栏:《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞,关注! 1、题…...
Deepseek本地部署小实践(c盘)
目录 前言 一、安装ollama 二、打开终端执行run 三、可视化 前言 小鲸鱼出来以后看到很多大佬本地部署AI,自己也想试一试,第一次部署AI,选了一个简单的办法,实践一下,写得比较粗糙。 一、安装ollama 先简单的介绍…...
详细解析d3dx9_27.dll丢失怎么办?如何快速修复d3dx9_27.dll
运行程序时提示“d3dx9_27.dll文件缺失”,通常由DirectX组件损坏或文件丢失引起。此问题可通过系统化修复方法解决,无需重装系统或软件。下文将详细说明具体步骤及注意事项。 一.d3dx9_27.dll缺失问题的本质解析 当系统提示“d3dx9_27.dll丢失”时&…...
【LeetCode刷题之路】leetcode155.最小栈
LeetCode刷题记录 🌐 我的博客主页:iiiiiankor🎯 如果你觉得我的内容对你有帮助,不妨点个赞👍、留个评论✍,或者收藏⭐,让我们一起进步!📝 专栏系列:LeetCode…...
矩阵乘积态简介
定义 矩阵乘积态(Matrix Product State, MPS)是一种用于表示量子多体系统的强大工具,特别是在一维系统中。MPS 是一种张量网络状态,它通过将全局量子态分解为一系列局部张量的乘积来有效地表示量子态。 注释: 量子态表…...
Oracle数据库分区自动删除
说明: 该存储过程部署后,设置成定时任务,每天执行。 每次执行删除partition_position 2的分区,删除之后,partition_position 3的分区会前移到partition_position 为 2; CREATE OR REPLACE PROCEDURE BILL_CENT_JI…...
华三交换机S5560 NQA测试
文章目录 NQA配置介绍实验说明 NQA配置介绍 NQA配置 nqa entry admin testtype icmp-echo //配置NQA类型destination ip 10.1.0.1 //配置探测的目的IPsource ip 10.1.0.2 //配置探测的源IPfrequency 6000 //配置探测的时间history-record enable //历史探测记录…...
Vue全局变量的定义和使用,创建 Store变量、读取、修改
在VUE中,当需要各js、各页面都能读写的全局变量时,可以用store变量,从定义到使用的方法如下 一.定义变量,例:我们定一个全局变量gxh 找到 vue的/ src/ store路径, 在 modules文件夹下创建文件gvar.js 在…...
基于Docker的前端环境管理:从开发环境到生产部署的实现方案
# 基于Docker的前端环境管理:从开发环境到生产部署的实现方案 简介及前端开发环境挑战 简介 是一种容器化平台,可以将应用程序及其依赖项打包为一个容器,提供一种轻量级、可移植的环境。它能够简化开发、部署和运维的流程,提高…...
单片机延时函数怎么写规范?
我们以前在开发产品的时候,肯定会碰到一些延时需求,比如常见的LED闪烁,按键消抖,控制IO口输出时序等等。 别小看延时,这个小问题,想做好,甚至要考虑到程序架构层面。 在开发板上,可能…...
数据结构 1-2 线性表的链式存储-链表
1 原理 顺序表的缺点: 插入和删除移动大量元素数组的大小不好控制占用一大段连续的存储空间,造成很多碎片 链表规避了上述顺序表缺点 逻辑上相邻的两个元素在物理位置上不相邻 头结点 L:头指针 头指针:链表中第一个结点的存储…...
vue2版本elementUI的table分页实现多选逻辑
1. 需求 我们需要在表格页上实现多选要求,该表格支持分页逻辑。 2. 认识属性 表格属性 参数说明类型可选值默认值data显示的数据array——row-key行数据的 Key,用来优化 Table 的渲染;在使用 reserve-selection 功能与显示树形数据时&…...
比特信噪比与信噪比SNR的换算公式
在无线通信系统中,比特信噪比与信噪比(SNR,通常指符号信噪比Es/N0)的换算: 核心公式 E b N 0 SNR R ⋅ log 2 M \boxed{ \frac{E_b}{N_0} \frac{\text{SNR}}{R \cdot \log_2 M} } N0EbR⋅log2MSNR 或…...
设计模式-解释器模式、装饰器模式
解释器模式 定义 给分析对象定义一个语言,并定义语言的文法表示,再设计一个解释器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。 类图 …...
C++初阶——简单实现list
目录 1、前言 2、List.h 3、Test.cpp 1、前言 1. 简单实现std::list,重点:迭代器,类模板,运算符重载。 2. 并不是,所有的类,都需要深拷贝,像迭代器类模板,只是用别的类的资源&am…...
linux 命令+相关配置记录(持续更新...)
linux 命令记录相关配置记录 磁盘切换 cd D:#这里表示切换到D盘查看wsl 安装的linux 子系统 wsl --list -vwsl 卸载 linux 子系统 wsl --unregister -xxx # xxx 表示子系统的名字备份Linux 子系统 导出 wsl --export xxx yyy # xxx 表示子系统的名字 yyy 表示压…...
【PDF预览】使用iframe实现pdf文件预览,加盖章
使用iframe实现pdf文件预览,以及在pdf上添加水印。另外还包括批注、打印、下载、缩放、分页等功能 <iframesrc"http://static.shanhuxueyuan.com/test.pdf"width"100%"height"100%"frameborder"0"></iframe>&l…...
网络运维学习笔记(DeepSeek优化版)002网工初级(HCIA-Datacom与CCNA-EI)子网划分与协议解析
文章目录 子网划分与协议解析1. VLSM与CIDR技术解析1.1 VLSM(Variable Length Subnetwork Mask,可变长子网掩码)1.2 CIDR(Classless Inter-Domain Routing,无类域间路由) 2. 子网划分方法与计算2.1 常规划分…...
在线骑行|基于SpringBoot的在线骑行网站设计与实现(源码+数据库+文档)
在线骑行网站系统 目录 基于SpringBoot的在线骑行设计与实现 一、前言 二、系统设计 三、系统功能设计 5.1用户信息管理 5.2 路线攻略管理 5.3路线类型管理 5.4新闻赛事管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取…...
BUUCTF-Web方向21-25wp
目录 [HCTF 2018]admin弱口令session伪造 [MRCTF2020]你传你🐎呢[护网杯 2018]easy_tornado[ZJCTF 2019]NiZhuanSiWei[MRCTF2020]Ez_bypass第一层第二层 [HCTF 2018]admin 打开环境,有三处提示,一个跳转链接,一个登录注册&#x…...
软考——WWW与HTTP
1.万维网(world wide web) 是一个规模巨大的、可以资源互联的资料空间。由URL进行定位,通过HTTP协议传送给使用者,又由HTML来进行文件的展现。 它的主要组成部分是:URL、HTTP、HTML。 (1)URL…...
GO 进行编译时插桩,实现零码注入
Go 编译时插桩 Go 语言的编译时插桩是一种在编译阶段自动注入监控代码的技术,目的是在不修改业务代码的情况下,实现对应用程序的监控和追踪。 基本原理 Go 编译时插桩的核心思想是通过在编译过程中对源代码进行分析和修改,将监控代码注入到…...
为人工智能驱动的交通研究增强路面传感器数据采集
论文标题 英文标题:Enhancing Pavement Sensor Data Harvesting for AI-Driven Transportation Studies 中文标题:为人工智能驱动的交通研究增强路面传感器数据采集 作者信息 Manish Kumar Krishne Gowda Purdue University, 465 Northwestern Avenue,…...
unordered_set和unordered_map的使用
Hello,今天我来为大家介绍一下前几年才刚刚新出的两个容器——unordered_map和unordered_set,这两个容器属于是map系列和set系列中的一种,和map/set不同的是它们的底层,map/set的底层是红黑树,而unordered_map/unorder…...
