C++Qt学习笔记——实现一个串口通信界面

news2025/2/25 9:11:34

C++Qt学习笔记——实现一个串口通信界面

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

参考以下视频

一.界面

在这里插入图片描述

二、项目结构

本项目包含以下功能模块:

  1. 接收区初始化:用于显示接收到的数据。
  2. 发送区初始化:用于输入并发送数据。
  3. 串口配置初始化:用于配置串口参数(如波特率、数据位等)。
  4. 串口操作:连接和断开串口,以及数据的发送和接收。
  5. 动态更新串口列表:定时扫描系统中的串口并更新下拉菜单。

三、头文件

#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_OBJECT

public:
    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/QMainWindowQMainWindow 是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,表示 QPlainTextEditSerialHelper 窗口的一部分。

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();

    • 单词解释:clearQPlainTextEdit 类的一个方法,用于清空文本内容。
    • 作用:在这里,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") {  // 如果发送模式为HEX
            QByteArray 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") {  // 如果接收模式为HEX
                QString 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);  // 启动定时器,每秒更新串口列表
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2304807.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Word(2010)排版技巧

设置标题样式 选择需要设置的标题 如下图所示。选择文字后&#xff0c;点击对应的样式即可设置。 设置标题格式 设置字体格式 设置段落格式 显示所有样式 标题样式展示 建议 建议新建一个正文样式&#xff0c;可以命名为正文1&#xff0c;因为所有的样式参考的“样式基准…

一.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&#xff1a;解锁高效开发的钥匙 在《Head First Java》的第六章节中&#xff0c;作者深入探讨了Java的API&#xff08;Application Programming Interface&#xff09;&#xff0c;并强调了它在Java开发中的重要性。Java API 是Java开发工具包&#xff08;JDK&a…

4 - AXI GPIO按键控制LED实验

文章目录 1 实验任务2 系统框图3 软件设计 1 实验任务 本实验任务是通过调用PL端AXI GPIO IP核&#xff0c;使用中断机制&#xff0c;实现PL端按键控制 PS端LED的功能。 2 系统框图 3 软件设计 注意事项&#xff1a; AXI GPIO IP核是双沿触发中断&#xff0c;不可设置&…

题海拾贝:扫雷

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…

Deepseek本地部署小实践(c盘)

目录 前言 一、安装ollama 二、打开终端执行run 三、可视化 前言 小鲸鱼出来以后看到很多大佬本地部署AI&#xff0c;自己也想试一试&#xff0c;第一次部署AI&#xff0c;选了一个简单的办法&#xff0c;实践一下&#xff0c;写得比较粗糙。 一、安装ollama 先简单的介绍…

详细解析d3dx9_27.dll丢失怎么办?如何快速修复d3dx9_27.dll

运行程序时提示“d3dx9_27.dll文件缺失”&#xff0c;通常由DirectX组件损坏或文件丢失引起。此问题可通过系统化修复方法解决&#xff0c;无需重装系统或软件。下文将详细说明具体步骤及注意事项。 一.d3dx9_27.dll缺失问题的本质解析 当系统提示“d3dx9_27.dll丢失”时&…

【LeetCode刷题之路】leetcode155.最小栈

LeetCode刷题记录 &#x1f310; 我的博客主页&#xff1a;iiiiiankor&#x1f3af; 如果你觉得我的内容对你有帮助&#xff0c;不妨点个赞&#x1f44d;、留个评论✍&#xff0c;或者收藏⭐&#xff0c;让我们一起进步&#xff01;&#x1f4dd; 专栏系列&#xff1a;LeetCode…

Vue全局变量的定义和使用,创建 Store变量、读取、修改

在VUE中&#xff0c;当需要各js、各页面都能读写的全局变量时&#xff0c;可以用store变量&#xff0c;从定义到使用的方法如下 一&#xff0e;定义变量&#xff0c;例&#xff1a;我们定一个全局变量gxh 找到 vue的/ src/ store路径, 在 modules文件夹下创建文件gvar.js 在…

基于Docker的前端环境管理:从开发环境到生产部署的实现方案

# 基于Docker的前端环境管理&#xff1a;从开发环境到生产部署的实现方案 简介及前端开发环境挑战 简介 是一种容器化平台&#xff0c;可以将应用程序及其依赖项打包为一个容器&#xff0c;提供一种轻量级、可移植的环境。它能够简化开发、部署和运维的流程&#xff0c;提高…

单片机延时函数怎么写规范?

我们以前在开发产品的时候&#xff0c;肯定会碰到一些延时需求&#xff0c;比如常见的LED闪烁&#xff0c;按键消抖&#xff0c;控制IO口输出时序等等。 别小看延时&#xff0c;这个小问题&#xff0c;想做好&#xff0c;甚至要考虑到程序架构层面。 在开发板上&#xff0c;可能…

数据结构 1-2 线性表的链式存储-链表

1 原理 顺序表的缺点&#xff1a; 插入和删除移动大量元素数组的大小不好控制占用一大段连续的存储空间&#xff0c;造成很多碎片 链表规避了上述顺序表缺点 逻辑上相邻的两个元素在物理位置上不相邻 头结点 L&#xff1a;头指针 头指针&#xff1a;链表中第一个结点的存储…

vue2版本elementUI的table分页实现多选逻辑

1. 需求 我们需要在表格页上实现多选要求&#xff0c;该表格支持分页逻辑。 2. 认识属性 表格属性 参数说明类型可选值默认值data显示的数据array——row-key行数据的 Key&#xff0c;用来优化 Table 的渲染&#xff1b;在使用 reserve-selection 功能与显示树形数据时&…

设计模式-解释器模式、装饰器模式

解释器模式 定义 给分析对象定义一个语言&#xff0c;并定义语言的文法表示&#xff0c;再设计一个解释器来解释语言中的句子。也就是说&#xff0c;用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口&#xff0c;该接口解释一个特定的上下文。 类图 …

linux 命令+相关配置记录(持续更新...)

linux 命令记录相关配置记录 磁盘切换 cd D&#xff1a;#这里表示切换到D盘查看wsl 安装的linux 子系统 wsl --list -vwsl 卸载 linux 子系统 wsl --unregister -xxx # xxx 表示子系统的名字备份Linux 子系统 导出 wsl --export xxx yyy # xxx 表示子系统的名字 yyy 表示压…

【PDF预览】使用iframe实现pdf文件预览,加盖章

使用iframe实现pdf文件预览&#xff0c;以及在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&#xff08;Variable Length Subnetwork Mask&#xff0c;可变长子网掩码&#xff09;1.2 CIDR&#xff08;Classless Inter-Domain Routing&#xff0c;无类域间路由&#xff09; 2. 子网划分方法与计算2.1 常规划分…

在线骑行|基于SpringBoot的在线骑行网站设计与实现(源码+数据库+文档)

在线骑行网站系统 目录 基于SpringBoot的在线骑行设计与实现 一、前言 二、系统设计 三、系统功能设计 5.1用户信息管理 5.2 路线攻略管理 5.3路线类型管理 5.4新闻赛事管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取…

BUUCTF-Web方向21-25wp

目录 [HCTF 2018]admin弱口令session伪造 [MRCTF2020]你传你&#x1f40e;呢[护网杯 2018]easy_tornado[ZJCTF 2019]NiZhuanSiWei[MRCTF2020]Ez_bypass第一层第二层 [HCTF 2018]admin 打开环境&#xff0c;有三处提示&#xff0c;一个跳转链接&#xff0c;一个登录注册&#x…