Qt+C++串口调试工具

程序示例精选
Qt+C++串口调试工具
如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助!

前言

这篇博客针对《Qt+C++串口调试工具》编写代码,代码整洁,规则,易读。 学习与应用推荐首选。


运行结果


文章目录

一、所需工具软件
二、使用步骤
       1. 主要代码
       2. 运行结果
三、在线协助

一、所需工具软件

       1. Qt
       2. C++

二、使用步骤

代码如下(示例):

void MainWindow::openReadWriter() {if (_readWriter != nullptr) {_readWriter->close();delete _readWriter;_readWriter = nullptr;emit serialStateChanged(false);}bool result;if (readWriterButtonGroup->checkedButton() == serialRadioButton) {_serialType = SerialType::Normal;auto settings = new SerialSettings();settings->name = serialPortNameComboBox->currentText();settings->baudRate = serialPortBaudRateComboBox->currentText().toInt();settings->dataBits = (QSerialPort::DataBits) serialPortDataBitsComboBox->currentText().toInt();settings->stopBits = (QSerialPort::StopBits) serialPortStopBitsComboBox->currentData().toInt();settings->parity = (QSerialPort::Parity) serialPortParityComboBox->currentData().toInt();auto readWriter = new SerialReadWriter(this);readWriter->setSerialSettings(*settings);qDebug() << settings->name << settings->baudRate << settings->dataBits << settings->stopBits<< settings->parity;result = readWriter->open();if (!result) {showWarning(tr("消息"), tr("串口被占用或者不存在"));return;}_readWriter = readWriter;_serialType = SerialType::Normal;} else if (readWriterButtonGroup->checkedButton() == tcpServerRadioButton) {_serialType = SerialType::TcpServer;auto address = tcpAddressLineEdit->text();bool ok;auto port = tcpPortLineEdit->text().toInt(&ok);if (!ok) {showMessage("", tr("端口格式不正确"));return;}auto readWriter = new TcpServerReadWriter(this);readWriter->setAddress(address);readWriter->setPort(port);qDebug() << address << port;result = readWriter->open();if (!result) {showWarning("", tr("建立服务器失败"));return;}connect(readWriter, &TcpServerReadWriter::currentSocketChanged, this, &MainWindow::updateTcpClient);connect(readWriter, &TcpServerReadWriter::connectionClosed, this, &MainWindow::clearTcpClient);_readWriter = readWriter;} else if (readWriterButtonGroup->checkedButton() == tcpClientRadioButton) {_serialType = SerialType::TcpClient;auto address = tcpAddressLineEdit->text();bool ok;auto port = tcpPortLineEdit->text().toInt(&ok);if (!ok) {showMessage("", tr("端口格式不正确"));return;}auto readWriter = new TcpClientReadWriter(this);readWriter->setAddress(address);readWriter->setPort(port);qDebug() << address << port;result = readWriter->open();if (!result) {showError("", tr("连接服务器失败"));return;}_readWriter = readWriter;} else if (readWriterButtonGroup->checkedButton() == serialBridgeRadioButton) {_serialType = SerialType::SerialBridge;auto settings1 = new SerialSettings();settings1->name = serialPortNameComboBox->currentText();settings1->baudRate = serialPortBaudRateComboBox->currentText().toInt();settings1->dataBits = (QSerialPort::DataBits) serialPortDataBitsComboBox->currentText().toInt();settings1->stopBits = (QSerialPort::StopBits) serialPortStopBitsComboBox->currentData().toInt();settings1->parity = (QSerialPort::Parity) serialPortParityComboBox->currentData().toInt();auto settings2 = new SerialSettings();settings2->name = secondSerialPortNameComboBox->currentText();settings2->baudRate = secondSerialPortBaudRateComboBox->currentText().toInt();settings2->dataBits = (QSerialPort::DataBits) secondSerialPortDataBitsComboBox->currentText().toInt();settings2->stopBits = (QSerialPort::StopBits) secondSerialPortStopBitsComboBox->currentText().toInt();settings2->parity = (QSerialPort::Parity) secondSerialPortParityComboBox->currentText().toInt();auto readWriter = new SerialBridgeReadWriter(this);readWriter->setSettings(*settings1, *settings2);result = readWriter->open();if (!result) {showWarning(tr("消息"), QString(tr("串口被占用或者不存在,%1")).arg(readWriter->settingsText()));return;}connect(readWriter, &SerialBridgeReadWriter::serial1DataRead, [this](const QByteArray &data) {showSendData(data);});connect(readWriter, &SerialBridgeReadWriter::serial2DataRead, [this](const QByteArray &data) {showReadData(data);});_readWriter = readWriter;} else {_serialType = SerialType::Bridge;auto settings = new SerialSettings();settings->name = serialPortNameComboBox->currentText();settings->baudRate = serialPortBaudRateComboBox->currentText().toInt();settings->dataBits = (QSerialPort::DataBits) serialPortDataBitsComboBox->currentText().toInt();settings->stopBits = (QSerialPort::StopBits) serialPortStopBitsComboBox->currentData().toInt();settings->parity = (QSerialPort::Parity) serialPortParityComboBox->currentData().toInt();auto address = tcpAddressLineEdit->text();bool ok;auto port = tcpPortLineEdit->text().toInt(&ok);if (!ok) {showMessage("", tr("端口格式不正确"));return;}auto readWriter = new BridgeReadWriter(this);readWriter->setSettings(*settings, address, static_cast<qint16>(port));result = readWriter->open();if (!result) {showWarning(tr("消息"), tr("串口被占用或者不存在"));return;}connect(readWriter, &BridgeReadWriter::currentSocketChanged,this, &MainWindow::updateTcpClient);connect(readWriter, &BridgeReadWriter::connectionClosed,this, &MainWindow::clearTcpClient);connect(readWriter, &BridgeReadWriter::serialDataRead, [this](const QByteArray &data) {showSendData(data);});connect(readWriter, &BridgeReadWriter::tcpDataRead, [this](const QByteArray &data) {showReadData(data);});_readWriter = readWriter;}connect(_readWriter, &AbstractReadWriter::readyRead,this, &MainWindow::readData);emit serialStateChanged(result);
}void MainWindow::closeReadWriter() {stopAutoSend();if (_readWriter != nullptr) {_readWriter->close();delete _readWriter;_readWriter = nullptr;}emit serialStateChanged(false);
}void MainWindow::createConnect() {connect(readWriterButtonGroup, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled),[=](QAbstractButton *button, bool checked) {if (checked && isReadWriterOpen()) {SerialType serialType;if (button == tcpServerRadioButton) {serialType = SerialType::TcpServer;} else if (button == tcpClientRadioButton) {serialType = SerialType::TcpClient;} else if (button == bridgeRadioButton) {serialType = SerialType::Bridge;} else {serialType = SerialType::Normal;}if (serialType != _serialType) {if (showWarning("", tr("串口配置已经改变,是否重新打开串口?"))) {openReadWriter();}}}});connect(this, &MainWindow::serialStateChanged, [this](bool isOpen) {setOpenButtonText(isOpen);QString stateText;if (isOpen) {stateText = QString(tr("串口打开成功,%1")).arg(_readWriter->settingsText());} else {stateText = QString(tr("串口关闭"));}skipSendCount = 0;updateStatusMessage(stateText);});connect(this, &MainWindow::readBytesChanged, this, &MainWindow::updateReadBytes);connect(this, &MainWindow::writeBytesChanged, this, &MainWindow::updateWriteBytes);connect(this, &MainWindow::currentWriteCountChanged, this, &MainWindow::updateCurrentWriteCount);connect(openSerialButton, &QPushButton::clicked, [=](bool value) {if (!isReadWriterOpen()) {openReadWriter();} else {closeReadWriter();}});connect(refreshSerialButton, &QPushButton::clicked, [=] {_dirty = true;updateSerialPortNames();});connect(saveReceiveDataButton, &QPushButton::clicked, this, &MainWindow::saveReceivedData);connect(clearReceiveDataButton, &QPushButton::clicked, this, &MainWindow::clearReceivedData);connect(saveSentDataButton, &QPushButton::clicked, this, &MainWindow::saveSentData);connect(clearSentDataButton, &QPushButton::clicked, this, &MainWindow::clearSentData);connect(autoSendCheckBox, &QCheckBox::clicked, [this] {autoSendTimer->stop();});connect(loopSendCheckBox, &QCheckBox::stateChanged, [this] {_loopSend = loopSendCheckBox->isChecked();});connect(resetLoopSendButton, &QPushButton::clicked, [this] {skipSendCount = 0;serialController->setCurrentCount(0);emit currentWriteCountChanged(0);});connect(currentSendCountLineEdit, &QLineEdit::editingFinished, [this] {bool ok;auto newCount = currentSendCountLineEdit->text().toInt(&ok);if (ok) {serialController->setCurrentCount(newCount);} else {currentSendCountLineEdit->setText(QString::number(serialController->getCurrentCount()));}});connect(sendLineButton, &QPushButton::clicked, [this] {if (!isReadWriterConnected()) {handlerSerialNotOpen();return;}if (autoSendState == AutoSendState::Sending) {stopAutoSend();} else {if (_dirty) {_dirty = false;_sendType = SendType::Line;updateSendData(hexCheckBox->isChecked(), sendTextEdit->toPlainText());updateSendType();}sendNextData();startAutoSendTimerIfNeed();}if (autoSendState == AutoSendState::Sending) {sendLineButton->setText(tr("停止"));} else {resetSendButtonText();}});connect(processTextButton, &QPushButton::clicked, [this] {openDataProcessDialog(sendTextEdit->toPlainText());});connect(clearTextButton, &QPushButton::clicked, [this]{sendTextEdit->clear();});connect(lineReturnButtonGroup, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled),[=](QAbstractButton *button, bool checked) {if (checked) {if (button == sendRReturnLineButton) {lineReturn = QByteArray("\r");} else if (button == sendNReturnLineButton) {lineReturn = QByteArray("\n");} else {lineReturn = QByteArray("\r\n");}}});connect(autoSendTimer, &QTimer::timeout,[this] {sendNextData();});connect(hexCheckBox, &QCheckBox::stateChanged, [this] {this->_dirty = true;});connect(sendTextEdit, &QTextEdit::textChanged, [this] {this->_dirty = true;});
}void MainWindow::setOpenButtonText(bool isOpen) {if (isOpen) {openSerialButton->setText(tr("关闭"));} else {openSerialButton->setText("打开");}
}void MainWindow::createActions() {openAct = new QAction(tr("&打开(&O)"), this);openAct->setShortcut(QKeySequence::Open);openAct->setStatusTip(tr("打开一个文件"));connect(openAct, &QAction::triggered, this, &MainWindow::open);saveAct = new QAction(tr("&保存(&S)"), this);saveAct->setShortcut(QKeySequence::Save);saveAct->setStatusTip(tr("保存一个文件"));connect(saveAct, &QAction::triggered, this, &MainWindow::save);validateDataAct = new QAction(tr("计算校验(&E)"), this);validateDataAct->setShortcut(tr("Ctrl+E"));validateDataAct->setStatusTip(tr("计算数据校验值"));connect(validateDataAct, &QAction::triggered, this, &MainWindow::openDataValidator);convertDataAct = new QAction(tr("数据转换(&T)"));convertDataAct->setShortcut(tr("Ctrl+T"));convertDataAct->setStatusTip(tr("数据转换"));connect(convertDataAct, &QAction::triggered, this, &MainWindow::openConvertDataDialog);dataProcessAct = new QAction(tr("数据处理(&P)"));dataProcessAct->setShortcut(tr("Ctrl+P"));dataProcessAct->setStatusTip(tr("数据处理"));connect(dataProcessAct, &QAction::triggered, [this] {openDataProcessDialog("");});
}void MainWindow::createMenu() {fileMenu = menuBar()->addMenu(tr("文件(&F)"));fileMenu->addAction(openAct);fileMenu->addAction(saveAct);toolMenu = menuBar()->addMenu(tr("工具(&T)"));toolMenu->addAction(validateDataAct);toolMenu->addAction(convertDataAct);toolMenu->addAction(dataProcessAct);
}void MainWindow::open() {auto lastDir = runConfig->lastDir;QString fileName = QFileDialog::getOpenFileName(this, tr("打开数据文件"), lastDir, "");if (fileName.isEmpty()) {return;}QFile file(fileName);if (file.open(QIODevice::ReadOnly)) {runConfig->lastDir = getFileDir(fileName);auto data = file.readAll();sendTextEdit->setText(QString::fromLocal8Bit(data));}
}void MainWindow::save() {saveReceivedData();
}void MainWindow::openDataValidator() {CalculateCheckSumDialog dialog(this);dialog.setModal(true);dialog.exec();
}void MainWindow::openConvertDataDialog() {ConvertDataDialog dialog(this);dialog.setModal(true);dialog.exec();
}void MainWindow::openDataProcessDialog(const QString &text) {DataProcessDialog dialog(text, this);dialog.setModal(true);int result = dialog.exec();if (result == QDialog::Accepted) {sendTextEdit->setText(dialog.text());}
}void MainWindow::displayReceiveData(const QByteArray &data) {if (pauseReceiveCheckBox->isChecked()) {return;}static QString s;s.clear();if (addReceiveTimestampCheckBox->isChecked()) {s.append("[").append(getTimestamp()).append("] ");}if (!s.isEmpty()) {s.append(" ");}if (displayReceiveDataAsHexCheckBox->isChecked()) {s.append(dataToHex(data));} else {s.append(QString::fromLocal8Bit(data));}if (addLineReturnCheckBox->isChecked() || addReceiveTimestampCheckBox->isChecked()) {receiveDataBrowser->append(s);} else {auto text = receiveDataBrowser->toPlainText();text.append(s);receiveDataBrowser->setText(text);receiveDataBrowser->moveCursor(QTextCursor::End);}
}void MainWindow::displaySentData(const QByteArray &data) {if (displaySendDataAsHexCheckBox->isChecked()) {sendDataBrowser->append(dataToHex(data));} else {sendDataBrowser->append(QString::fromLocal8Bit(data));}
}void MainWindow::sendNextData() {if (isReadWriterConnected()) {if (skipSendCount > 0) {auto delay = skipSendCount * sendIntervalLineEdit->text().toInt();updateStatusMessage(QString("%1毫秒后发送下一行").arg(delay));skipSendCount--;return;}qDebug() << "sendNextData readEnd:" << serialController->readEnd() << "current:"<< serialController->getCurrentCount();if (!_loopSend && autoSendCheckBox->isChecked() && serialController->readEnd()) {serialController->setCurrentCount(0);stopAutoSend();return;}auto data = serialController->readNextFrame();if (data.isEmpty()) {updateStatusMessage(tr("空行,不发送"));if (autoSendCheckBox->isChecked()) {auto emptyDelay = emptyLineDelayLindEdit->text().toInt();auto sendInterval = sendIntervalLineEdit->text().toInt();if (emptyDelay > sendInterval) {skipSendCount = emptyDelay / sendInterval;if (emptyDelay % sendInterval != 0) {skipSendCount += 1;}skipSendCount--;updateStatusMessage(QString(tr("空行,%1毫秒后发送下一行")).arg(emptyDelay));}}emit currentWriteCountChanged(serialController->getCurrentCount());return;}writeData(data);if (sendLineReturnCheckBox->isChecked()) {writeData(lineReturn);}if (hexCheckBox->isChecked()) {updateStatusMessage(QString(tr("发送 %1")).arg(QString(dataToHex(data))));} else {updateStatusMessage(QString(tr("发送 %1")).arg(QString(data)));}emit currentWriteCountChanged(serialController->getCurrentCount());} else {handlerSerialNotOpen();}
}void MainWindow::updateSendData(bool isHex, const QString &text) {if (serialController != nullptr) {QStringList lines = getLines(text);QList<QByteArray> dataList;if (isHex) {for (auto &line :lines) {dataList << dataFromHex(line);}} else {for (auto &line:lines) {dataList << line.toLocal8Bit();}}serialController->setData(dataList);totalSendCount = serialController->getTotalCount();updateTotalSendCount(totalSendCount);}
}void MainWindow::readSettings() {qDebug() << "readSettings";updateSerialPortNames();QSettings settings("Zhou Jinlong", "Serial Wizard");settings.beginGroup("Basic");auto serialType = SerialType(settings.value("serial_type", static_cast<int >(SerialType::Normal)).toInt());if (serialType == SerialType::TcpServer) {tcpServerRadioButton->setChecked(true);} else if (serialType == SerialType::TcpClient) {tcpClientRadioButton->setChecked(true);} else if (serialType == SerialType::Bridge) {bridgeRadioButton->setChecked(true);} else if (serialType == SerialType::SerialBridge) {serialBridgeRadioButton->setChecked(true);} else {serialRadioButton->setChecked(true);}_serialType = serialType;settings.beginGroup("SerialSettings");auto nameIndex = settings.value("name", 0).toInt();auto baudRateIndex = settings.value("baud_rate", 5).toInt();auto dataBitsIndex = (QSerialPort::DataBits) settings.value("data_bits", 3).toInt();auto stopBitsIndex = (QSerialPort::StopBits) settings.value("stop_bits", 0).toInt();auto parityIndex = (QSerialPort::Parity) settings.value("parity", 0).toInt();auto sendText = settings.value("send_text", "").toString();auto maxCount = serialPortNameComboBox->maxCount();if (nameIndex > maxCount - 1) {nameIndex = 0;}serialPortNameComboBox->setCurrentIndex(nameIndex);serialPortBaudRateComboBox->setCurrentIndex(baudRateIndex);serialPortDataBitsComboBox->setCurrentIndex(dataBitsIndex);serialPortStopBitsComboBox->setCurrentIndex(stopBitsIndex);serialPortParityComboBox->setCurrentIndex(parityIndex);auto name2Index = settings.value("name2", 0).toInt();auto baudRate2Index = settings.value("baud_rate2", 5).toInt();auto dataBits2Index = (QSerialPort::DataBits) settings.value("data_bits2", 3).toInt();auto stopBits2Index = (QSerialPort::StopBits) settings.value("stop_bits2", 0).toInt();auto parity2Index = (QSerialPort::Parity) settings.value("parity2", 0).toInt();auto maxCount2 = serialPortNameComboBox->maxCount();if (name2Index > maxCount2 - 1) {name2Index = 0;}secondSerialPortNameComboBox->setCurrentIndex(name2Index);secondSerialPortBaudRateComboBox->setCurrentIndex(baudRate2Index);secondSerialPortDataBitsComboBox->setCurrentIndex(dataBits2Index);secondSerialPortStopBitsComboBox->setCurrentIndex(stopBits2Index);secondSerialPortParityComboBox->setCurrentIndex(parity2Index);settings.beginGroup("SerialReceiveSettings");auto addLineReturn = settings.value("add_line_return", true).toBool();auto displayReceiveDataAsHex = settings.value("display_receive_data_as_hex", false).toBool();auto addTimestamp = settings.value("add_timestamp", false).toBool();addLineReturnCheckBox->setChecked(addLineReturn);displayReceiveDataAsHexCheckBox->setChecked(displayReceiveDataAsHex);addReceiveTimestampCheckBox->setChecked(addTimestamp);settings.beginGroup("SerialSendSettings");auto sendAsHex = settings.value("send_as_hex", false).toBool();auto displaySendData = settings.value("display_send_data", false).toBool();auto displaySendDataAsHex = settings.value("display_send_data_as_hex", false).toBool();auto autoSend = settings.value("auto_send", false).toBool();auto autoSendInterval = settings.value("auto_send_interval", 100).toInt();auto emptyLineDelay = settings.value("empty_line_delay", 0).toInt();auto loopSend = settings.value("loop_send", false).toBool();hexCheckBox->setChecked(sendAsHex);displaySendDataCheckBox->setChecked(displaySendData);displaySendDataAsHexCheckBox->setChecked(displaySendDataAsHex);autoSendCheckBox->setChecked(autoSend);loopSendCheckBox->setChecked(loopSend);sendIntervalLineEdit->setText(QString::number(autoSendInterval));emptyLineDelayLindEdit->setText(QString::number(emptyLineDelay));auto sendLineReturn = settings.value("send_line_return", false).toBool();sendLineReturnCheckBox->setChecked(sendLineReturn);auto sendLineReturnType = LineReturn(settings.value("send_line_return_type", static_cast<int >(LineReturn::RN)).toInt());if (sendLineReturnType == LineReturn::R) {sendRReturnLineButton->setChecked(true);} else if (sendLineReturnType == LineReturn::N) {sendNReturnLineButton->setChecked(true);} else {sendRNLineReturnButton->setChecked(true);}settings.beginGroup("TcpSettings");auto ipList = getNetworkInterfaces();auto ipAddress = settings.value("tcp_address", "").toString();QString selectAddress = "";if (!ipAddress.isEmpty() && !ipList.isEmpty()) {auto found = false;for (const auto &ip:ipList) {if (getIpAddress(ip) == ipAddress) {selectAddress = ipAddress;found = true;break;}}if (!found) {selectAddress = getIpAddress(ipList.first());}}if (selectAddress.isEmpty()) {if (!ipList.isEmpty()) {do {for (const auto &ip:ipList) {if (ip.type() == QNetworkInterface::Wifi && !getIpAddress(ip).isEmpty()) {selectAddress = getIpAddress(ip);break;}}if (!selectAddress.isEmpty()) {break;}for (const auto &ip:ipList) {if (ip.type() == QNetworkInterface::Ethernet && !getIpAddress(ip).isEmpty()) {selectAddress = getIpAddress(ip);}}if (!selectAddress.isEmpty()) {break;}selectAddress = getIpAddress(ipList.first());} while (false);}}tcpAddressLineEdit->setText(selectAddress);auto tcpPort = settings.value("tcp_port").toInt();tcpPortLineEdit->setText(QString::number(tcpPort));sendTextEdit->setText(sendText);settings.beginGroup("RunConfig");auto lastDir = settings.value("last_dir", "").toString();auto lastFilePath = settings.value("last_file_path", "").toString();runConfig = new RunConfig;runConfig->lastDir = lastDir;runConfig->lastFilePath = lastFilePath;_loopSend = loopSend;serialController = new LineSerialController();updateSendType();
}
运行结果

三、在线协助:

如需安装运行环境或远程调试,见文章底部个人 QQ 名片,由专业技术人员远程协助!

1)远程安装运行环境,代码调试
2)Visual Studio, Qt, C++, Python编程语言入门指导
3)界面美化
4)软件制作
5)云服务器申请
6)网站制作

当前文章连接:https://blog.csdn.net/alicema1111/article/details/132666851
个人博客主页:https://blog.csdn.net/alicema1111?type=blog
博主所有文章点这里:https://blog.csdn.net/alicema1111?type=blog

博主推荐:
Python人脸识别考勤打卡系统:
https://blog.csdn.net/alicema1111/article/details/133434445
Python果树水果识别:https://blog.csdn.net/alicema1111/article/details/130862842
Python+Yolov8+Deepsort入口人流量统计:https://blog.csdn.net/alicema1111/article/details/130454430
Python+Qt人脸识别门禁管理系统:https://blog.csdn.net/alicema1111/article/details/130353433
Python+Qt指纹录入识别考勤系统:https://blog.csdn.net/alicema1111/article/details/129338432
Python Yolov5火焰烟雾识别源码分享:https://blog.csdn.net/alicema1111/article/details/128420453
Python+Yolov8路面桥梁墙体裂缝识别:https://blog.csdn.net/alicema1111/article/details/133434445
Python+Yolov5道路障碍物识别:https://blog.csdn.net/alicema1111/article/details/129589741
Python+Yolov5跌倒检测 摔倒检测 人物目标行为 人体特征识别:https://blog.csdn.net/alicema1111/article/details/129272048

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis基础操作-删除

Mybatis基础操作-删除 删除 package com.itheima.mapper;import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Mapper;Mapper //在运行时&#xff0c;会自动生成该接口的实现类对象&#xff08;代理对象&#xff09;&#xff0c;并且将该对象…

Vue3知识总结-4

Vue3知识总结-4 文章目录 Vue3知识总结-4插槽Slots渲染作用域默认内容具名插槽插槽中的数据传递具名插槽传递数据 组件声明周期声明周期示意图 组件生命周期的应用动态组件组件保持存活组件被卸载 异步组件依赖注入 插槽Slots 在某些场景中&#xff0c;可能想要为子组件传递一…

redis中的集群模式

主从复制、主从同步(解决高并发读的问题) 主从同步原理&#xff1a; 1.全量同步 slave&#xff08;从节点&#xff09;每次请求数据同步会带两个参数&#xff1a;replid和offset。 replid&#xff1a;第一次请求同步时&#xff0c;replid和master的replid不一样&#xff0c;这…

线性系统(一)

线性系统&#xff08;一&#xff09; 1.什么是线性系统2.高斯消元法3.高斯-约旦消元法4.线性方程组解的结构 链接: 线性系统&#xff08;二&#xff09; 1.什么是线性系统 线性&#xff1a;未知数只能是一次方项 非线性: 同时&#xff0c;读者也可以通过作图来更直观地感受&…

TypeScript高级类型 在鸿蒙中的使用 Partial、Required、Readonly、Pick、Record

我的工程代码在这里&#xff0c;持续更新中 欢迎交流&#xff0c;谢谢 https://github.com/MartinLi89/WanHarmony Partial <Type> 新定义 一个类型&#xff0c;将所有属性变为可选的类. class TextTS {a: string "1"b: string "2"c: string &…

即插即用篇 | YOLOv8引入轴向注意力 Axial Attention | 多维变换器中的轴向注意力

本改进已集成到 YOLOv8-Magic 框架。 我们提出了Axial Transformers,这是一个基于自注意力的自回归模型,用于图像和其他组织为高维张量的数据。现有的自回归模型要么因高维数据的计算资源需求过大而受到限制,要么为了减少资源需求而在分布表达性或实现的便捷性上做出妥协。相…

ppt通过修改幻灯片母版修改页脚

修改幻灯片母版 幻灯片母版就可以了&#xff0c;就可以修改页脚

数学建模——农村公交与异构无人机协同配送优化

目录 1.题目 2.问题1 1. 问题建模 输入数据 ​编辑 2. 算法选择 3.数据导入 3.模型构建 1. 距离计算 2. 优化模型 具体步骤 进一步优化 1. 重新定义问题 2. 变量定义 3. 优化目标 具体步骤 再进一步优化 具体实现步骤 1. 计算距离矩阵 2. 变量定义 3. 约束…

基于Django的图书管理系统

文章目录 前言一、页面展示1.登录2.前端页面3.后端页面 二、项目上传&#xff08;1&#xff09;导入数据库&#xff08;2&#xff09;导入项目&#xff08;3&#xff09;数据库密码修改&#xff08;4&#xff09;进入网站 总结 前言 本网站调用Django编写了图书管理网站&#…

漫谈AI时代的手机

以chatGPT 为代表的大语言的横空出世使人们感受到AI 时代的到来&#xff0c;大语言模型技术的最大特点是机器能”懂人话“&#xff0c;”说人话“了。如同历史上任何一个革命性工具的出现一样&#xff0c;它必将对人类生活和工作产生巨大的影响。 在这里。我们不妨畅想一下啊AI…

返回分类信息(带层级)

文章目录 1.前端展示分类管理信息1.目前项目架构2.启动前后端项目1.启动mysql容器2.启动后端 renren-fast3.启动前端1.界面2.用户名密码都是admin 3.创建分类管理菜单1.菜单管理 -> 新增 -> 新增目录2.刷新3.能够新增菜单的原因是前端脚手架与renren-fast后端脚手架通信&…

Linux基础之僵尸进程与孤儿进程

目录 一、僵尸进程 1.1 什么是僵尸进程 1.2 为什么要有僵尸状态 1.3 观察我们的僵尸状态 1.4 关于僵尸进程的小Tip 二、孤儿进程 2.1 什么是孤儿进程 一、僵尸进程 1.1 什么是僵尸进程 在上一篇文章中&#xff0c;我们有提到过进程的死亡状态的概念&#xff0c;而我们的…

国内智能搜索工具实战教程

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

c++AVL树的模拟实现

前面对map/multimap/set/multiset进行了简单的介绍&#xff0c;在其文档介绍中发现&#xff0c;这几个容器有个 共同点是&#xff1a;其底层都是按照二叉搜索树来实现的&#xff0c;但是二叉搜索树有其自身的缺陷&#xff0c;假如往树中 插入的元素有序或者接近有序&#xff0c…

k8s 二进制安装 优化架构之 部署负载均衡,加入master02

目录 一 实验环境 二 部署 CoreDNS 1&#xff0c;所有node加载coredns.tar 镜像 2&#xff0c;在 master01 节点部署 CoreDNS 3&#xff0c; DNS 解析测试 4&#xff0c; 报错分析 5&#xff0c;重新 DNS 解析测试 三 master02 节点部署 1&#xff0…

什么是最大路径?什么是极大路径?

最近学习中&#xff0c;在这两个概念上出现了混淆&#xff0c;导致了一些误解&#xff0c;在此厘清。 最大路径 在一个简单图G中&#xff0c;u、v之间的距离 d ( u , v ) min ⁡ { u 到 v 的最短路的长度 } d(u,v) \min \{ u到v的最短路的长度 \} d(u,v)min{u到v的最短路的…

Redis 的主从复制

Redis 的主从复制 1、主从复制的实现2、主从复制的同步功能(PSYNC)2.1、部分重同步 本文讲解的Redis 主从复制机制&#xff0c;是基于 2.8及以后的版本而言&#xff0c;2.8以前的版本主从复制机制与此有所不同&#xff0c;请知悉。 Redis的复制功能分为 同步 (psync) 和 命令传…

vm16安装最新版本的ubuntu虚拟机,并安装g++的步骤记录

背景 低版本的ubuntu安装G一直不成功&#xff0c;干脆安装最新版的 官网下载 bing搜索ubuntu 下载完成 vm16新建虚拟机 一直下一步&#xff0c;安装完成 终端输入命令 sudo apt-get update ᅟᅠ       sudo apt install gcc ᅟᅠ      sudo apt install g

【C/C++】设计模式——工厂模式:简单工厂、工厂方法、抽象工厂

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

cdn引入vue的项目嵌入vue组件——http-vue-loader 的使用——技能提升

最近在写MVC的后台&#xff0c;看到全是jq的写法&#xff0c;但是对于用惯了vue的我&#xff0c;真是让我无从下手。。。 vue的双向绑定真的很好用。。。 为了能够在cdn引入的项目中嵌入vue组件&#xff0c;则可以使用http-vue-loader了 步骤1&#xff1a;下载http-vue-loader…