Qt+C++串口调试接收发送数据曲线图

程序示例精选

Qt+C++串口调试接收发送数据曲线图

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

前言

这篇博客针对<<Qt+C++串口调试接收发送数据曲线图>>编写代码,代码整洁,规则,易读。 学习与应用推荐首选。


文章目录

一、所需工具软件

二、使用步骤

        1. 引入库

        2. 代码实现

        3. 运行结果

三、在线协助

一、所需工具软件

1. VS, Qt

2. C++

二、使用步骤

1.引入库

#include <QAction>
#include <QCheckBox>
#include <QDragEnterEvent>
#include <QDebug>
#include <QLineEdit>
#include <QMenu>
#include <QMenuBar>
#include <QtSerialPort/QSerialPort>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QGroupBox>
#include <QTextBrowser>
#include <QtWidgets/QFileDialog>
#include <QTimer>
#include <QtCore/QSettings>
#include <QtCore/QProcess>
#include <QStatusBar>
#include <QSplitter>
#include <data/SerialReadWriter.h>
#include <data/TcpServerReadWriter.h>
#include <data/TcpClientReadWriter.h>
#include <QRadioButton>
#include <QButtonGroup>
#include <data/BridgeReadWriter.h>
#include <QMimeData>
#include <QtSerialPort/QSerialPortInfo>
#include <data/SerialBridgeReadWriter.h>
#include <utils/FileUtil.h>
#include <QTextCodec>

2. 代码实现

代码如下:

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

3. 运行结果

动画演示

 

三、在线协助:

如需安装运行环境或远程调试,见文章底部个人 QQ 名片,由专业技术人员远程协助!
1)远程安装运行环境,代码调试
2)Qt, C++, Python入门指导
3)界面美化
4)软件制作

当前文章连接:Python+Qt桌面端与网页端人工客服沟通工具_alicema1111的博客-CSDN博客

博主推荐文章:python人脸识别统计人数qt窗体-CSDN博客

博主推荐文章:Python Yolov5火焰烟雾识别源码分享-CSDN博客

                         Python OpenCV识别行人入口进出人数统计_python识别人数-CSDN博客

个人博客主页:alicema1111的博客_CSDN博客-Python,C++,网页领域博主

博主所有文章点这里alicema1111的博客_CSDN博客-Python,C++,网页领域博主

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

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

相关文章

探索GreatADM:图形化部署MGR的全新体验

摘要&#xff1a; 在DBA的日常工作中&#xff0c;快速部署数据库高可用架构&#xff0c;且标准化地入网部署数据库是一项重要的基础任务。本文将介绍常见的部署MGR的方式&#xff0c;并重点介绍万里数据库的GreatADM数据库管理平台进行图形化、可视化、标准化的部署过程&#x…

vue 学习笔记 简单实验

1.代码(html) <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"counter">Counter: {{ counter }} </div> <script> const Counter {data() {return {counter: 5}} } Vue.cr…

二、pikachu之SQL注入(2)

文章目录 1、delete注入2、http header注入3、布尔盲注4、时间盲注 4、宽字节注入 1、delete注入 &#xff08;1&#xff09;寻找传参页面&#xff0c;在删除留言的时候&#xff0c;发现是get传参&#xff1b; &#xff08;2&#xff09;判断是否存在注入点&#xff0c;命令&…

Shell语法揭秘:深入探讨常见Linux Shell之间的语法转换

深入探讨常见Linux Shell之间的语法转换 一、引言二、Linux常用Shell&#xff1a;Bash、Zsh、Ksh、Csh、Tcsh和Fish的简介2.1、Bash、Zsh、Ksh、Csh、Tcsh和Fish的特点和用途2.2、语法差异是常见Shell之间的主要区别 三、变量和环境设置的语法差异3.1、变量定义和使用的不同语法…

Redis——set类型详解

概要 Set&#xff08;集合&#xff09;&#xff0c;将一些有关联的数据放到一起&#xff0c;集合中的元素是无序的&#xff0c;并且集合中的元素是不能重复的 之前介绍的list就是有序的&#xff0c;对于列表来说[1, 2, 3] 和 [2, 1, 3]是两个不同的列表&#xff0c;而对于集合…

GraphScope,开源图数据分析引擎的领航者

文章首发地址 GraphScope是一个开源的大规模图数据分析引擎&#xff0c;由Aliyun、阿里巴巴集团和华为公司共同开发。GraphScope旨在为大规模图数据处理和分析提供高性能、高效率的解决方案。 Github地址&#xff1a; https://github.com/alibaba/GraphScope GraphScope 的重…

开发第一个gPRC的开发

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

网络综合布线实训室方案(2023版)

综合布线实训室概述 随着智慧城市的蓬勃发展,人工智能、物联网、云计算、大数据等新兴行业也随之崛起,网络布线系统作为现代智慧城市、智慧社区、智能建筑、智能家居、智能工厂和现代服务业的基础设施和神经网络,发挥着重要作用。实践表明,网络系统故障的70%发生在布线系统,直接…

苹果手机桌面APP带云图标有个箭头,过一段时间经常要下载才能使用APP

环境&#xff1a; IPhone 11 IOS13.0 问题描述&#xff1a; 苹果手机桌面APP带云图标有个箭头&#xff0c;过一段时间经常要下载才能使用APP 解决方案&#xff1a; 1.打开设置&#xff0c;往下找到iTunes Store与App Store 2.找到下面卸载未使用的APP 关闭按钮

最优的家电设备交互方式是什么?详解家电设备交互的演进之旅

家电&#xff0c;在人们的日常生活中扮演着不可或缺的角色&#xff0c;也是提升人们幸福感的重要组成部分&#xff0c;那你了解家电的发展史吗&#xff1f; 70年代 结婚流行“四大件”&#xff1a;手表、自行车、缝纫机&#xff0c;收音机&#xff0c;合成“三转一响”。 80年…

问题描述:在Windows下没有预装ImageMagick工具

问题描述:在Windows下没有预装ImageMagick工具 # WInR输入cmd回车进入命令行,执行以下命令查看版本信息 magick --version没有预装ImageMagick工具 解决方案&#xff1a;下载安装ImageMagick 官网下载:ImageMagick-7.1.1-15-Q16-x64-dll.exe 下载之后&#xff0c;一路下一步…

MySQL表的约束

MySQL表的约束 约束的概念空属性默认值列描述zerofill主键自增长唯一键外键 约束的概念 在正式谈MySQL表的约束之前&#xff0c;我们先来简单理解一下约束这个概念; 约束&#xff1a;意思是指带有束缚、限制、管束等意思&#xff1b; 大白话就是说:规定了那些事情你不能干&…

如何大幅提高遥感影像分辨率(Python+MATLAB)

前言&#xff1a; 算法&#xff1a;NSCT算法&#xff08;非下采样变换&#xff09; 数据&#xff1a;Landsat8 OLI 遥感图像数据 编程平台&#xff1a;MATLABPython 论文参考&#xff1a;毛克.一种快速的全色和多光谱图像融合算法[J].测绘科学,2016,41(01):151-15398.DOI:10.1…

k8s deployment创建pod流程图

参考 k8s 创建pod和deployment的流程 - SoulChild随笔记

TCP的可靠性之道:确认重传和流量控制

TCP 全称为 Transmission Control Protocol&#xff08;传输控制协议&#xff09;&#xff0c;是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;其中可靠性是相对于其他传输协议的优势点。TCP 为了确保数据传输的可靠性主要做了以下几点&#xff1a; 发送确…

【vue3+ts项目】配置husky+配置commitlint

上一篇文章中配置了eslint校验代码工具 【vue3ts项目】配置eslint校验代码工具&#xff0c;eslintprettierstylelint 1、配置husky 每次手动执行命令才能格式化代码&#xff0c;如果有人没有格式化就提交到远程仓库&#xff0c;这个规范就起不到作用了&#xff0c;所有需要强…

Java日志框架概览

SLF4J 提供统一的日志门面API&#xff0c;即图中紫色部分&#xff0c;实现中立的日志记录API 桥接功能&#xff0c;蓝色部分&#xff0c;把各种日志框架API&#xff08;绿色部分&#xff09;桥接到SLF4J API。这样即便你的程序中使用各种日志API记录日志&#xff0c;最终都可桥…

带你了解SpringBoot---开启Durid 监控

文章目录 数据库操作--开启Durid 监控整合Druid 到Spring-Boot官方文档基本介绍Durid 基本使用代码实现 Durid 监控功能-SQL 监控需求:SQL 监控数据SQL 监控数据-测试页面 Durid 监控功能-Web 关联监控需求:Web 关联监控配置-Web 应用、URI 监控重启项目 Durid 监控功能-SQL 防…

进程调度和进程切换——《王道考研》

一、王道书咋说 二、chatgpt咋说 进程调度和进程切换是多道程序操作系统中两个关键的概念&#xff0c;它们在处理多个进程时起着不同的作用。 2.1进程调度是指&#xff1a; 操作系统根据一定的调度算法&#xff0c;从就绪态的进程队列中选择一个进程来占用CPU资源&#xff0…

最新消息:谷歌将在Chromebook上运用UWB技术,无线通信更上一层

超宽带&#xff08;UWB&#xff09;技术是一种创新的短距离无线通信技术&#xff0c;具有高速数据传输和精确定位物体位置的优势。尽管该技术已经存在一段时间&#xff0c;但最近开始广泛应用于各种设备中。据最新报道&#xff0c;Pixel Watch 2可能会搭载UWB模块&#xff0c;这…