当前位置: 首页 > news >正文

【QT用户登录与界面跳转】

【QT用户登录与界面跳转】

  • 1.前言
  • 2. 项目设置
  • 3.设计登录界面
    • 3.1 login.pro参数
    • 3.2 界面设置
      • 3.2.1 登录界面
      • 3.2.2 串口主界面
  • 4. 实现登录逻辑
  • 5.串口界面
  • 6.测试功能
  • 7.总结

1.前言

在Qt应用程序开发中,实现用户登录及界面跳转功能是构建交互式应用的重要步骤之一。下面将介绍如何使用Qt框架来创建一个简单的用户登录界面,并根据用户的输入信息进行验证,然后跳转到相应的【QT串口助手】主界面。
源码地址:

2. 项目设置

首先,确保你的开发环境中已安装了Qt及其相关工具(如Qt Creator),前期也安装过QT(参考博客:【Qt安装与简易串口控制Arduino开发板小灯教程】)。本文记录一下用QT Creator 写一个用户登录与界面串口助手的过程,整个工程只有几百行代码,跟着做下来对新手来说可以更快了解整个QT项目的开发过程和一些常用控件的使用方法。最好每个功能自己都试试增加自信心!
💕💕💕
先来看看作品:
在这里插入图片描述

3.设计登录界面

3.1 login.pro参数

  1. 设置login.pro参数,导入core gui serialport库
 QT       += core gui serialportgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \mainwindow.cpp \serial.cppHEADERS += \mainwindow.h \serial.hFORMS += \mainwindow.ui \serial.ui# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += targetRESOURCES += \source.qrc

3.2 界面设置

界面设置分为登录界面和串口主界面

3.2.1 登录界面

在这里插入图片描述
这个登录界面是为智能船舶自主航行系统设计的,提供了简洁而功能齐全的用户登录体验。界面顶部展示有系统名称,明确了这是进入系统的入口。用户需要输入账号和密码来验证身份,其中密码输入框支持显示或隐藏密码的功能以增强使用便捷性。此外,提供了一个“记住账号密码”的选项,方便用户的下次登录。整个背景采用了半透明处理的船舶图像,既美化了界面也强化了品牌形象,使得登录过程更加直观友好。底部还设有一个“忘记密码”链接,为用户提供了找回密码的途径。整体设计注重用户体验,确保了安全性和易用性的平衡。
mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>MainWindow</class><widget class="QMainWindow" name="MainWindow"><property name="geometry"><rect><x>0</x><y>0</y><width>501</width><height>403</height></rect></property><property name="windowTitle"><string>MainWindow</string></property><widget class="QWidget" name="centralwidget"><widget class="QFrame" name="frame"><property name="geometry"><rect><x>30</x><y>20</y><width>431</width><height>351</height></rect></property><property name="frameShape"><enum>QFrame::StyledPanel</enum></property><property name="frameShadow"><enum>QFrame::Raised</enum></property><widget class="QGroupBox" name="groupBox"><property name="geometry"><rect><x>20</x><y>20</y><width>391</width><height>311</height></rect></property><property name="font"><font><pointsize>14</pointsize></font></property><property name="title"><string>智能船舶自主航行系统软件登录</string></property><widget class="QPushButton" name="pushButton"><property name="geometry"><rect><x>100</x><y>260</y><width>161</width><height>41</height></rect></property><property name="font"><font><pointsize>20</pointsize></font></property><property name="text"><string>登录</string></property></widget><widget class="QCheckBox" name="checkBox"><property name="geometry"><rect><x>80</x><y>230</y><width>121</width><height>21</height></rect></property><property name="font"><font><pointsize>11</pointsize></font></property><property name="text"><string>记住账号密码</string></property></widget><widget class="QCommandLinkButton" name="commandLinkButton"><property name="geometry"><rect><x>220</x><y>220</y><width>101</width><height>41</height></rect></property><property name="font"><font><family>Segoe UI</family><pointsize>11</pointsize></font></property><property name="text"><string>忘记密码</string></property></widget><widget class="QLineEdit" name="accout"><property name="geometry"><rect><x>100</x><y>90</y><width>201</width><height>31</height></rect></property></widget><widget class="QLineEdit" name="password"><property name="geometry"><rect><x>100</x><y>150</y><width>201</width><height>31</height></rect></property></widget><widget class="QLabel" name="label"><property name="geometry"><rect><x>40</x><y>90</y><width>71</width><height>31</height></rect></property><property name="font"><font><family>华文中宋</family><pointsize>14</pointsize></font></property><property name="text"><string>账号:</string></property></widget><widget class="QLabel" name="label_2"><property name="geometry"><rect><x>40</x><y>150</y><width>71</width><height>31</height></rect></property><property name="font"><font><family>华文中宋</family><pointsize>14</pointsize></font></property><property name="text"><string>密码:</string></property></widget><widget class="QRadioButton" name="radioButton"><property name="geometry"><rect><x>310</x><y>155</y><width>81</width><height>21</height></rect></property><property name="text"><string>显示</string></property></widget></widget></widget></widget></widget><resources/><connections/>
</ui>

3.2.2 串口主界面

在这里插入图片描述
该串口工具界面设计用于简化与串行设备的通信过程,设计过程参考【QT串口助手】,提供直观的操作体验。界面主要分为几个关键部分:

  • 串口配置区域:用户可以在此选择和配置串口参数,包括端口号、波特率、数据位、校验位以及停止位,以确保与目标设备正确匹配。
  • 操作控制按钮:包含检测串口、打开/关闭串口等按钮,便于用户快速操作串口连接状态。
  • 接收设置选项:允许用户根据需求调整接收数据的方式,如启用Hex显示模式、添加时间戳以及自动换行功能,方便查看接收到的数据。
  • 发送设置选项:提供Hex发送模式及发送后自动换行的功能,同时支持设定自动发送间隔时间,适合需要周期性发送数据的应用场景。
  • 数据交互区:分为发送数据区和接收数据显示区,前者让用户输入要发送到串口的数据,后者实时展示从串口接收到的信息,两者均配备了清空内容的快捷按钮,提升用户体验。

整体而言,此串口界面旨在为用户提供一个高效且易于使用的平台,以便于进行串口通信调试和管理,满足不同应用场景下的串口操作需求。
serial.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>Serial</class><widget class="QMainWindow" name="Serial"><property name="geometry"><rect><x>0</x><y>0</y><width>578</width><height>527</height></rect></property><property name="windowTitle"><string>MainWindow</string></property><widget class="QWidget" name="centralwidget"><widget class="QGroupBox" name="groupBox_4"><property name="geometry"><rect><x>200</x><y>10</y><width>351</width><height>481</height></rect></property><property name="title"><string>数据交互</string></property><widget class="QWidget" name="formLayoutWidget"><property name="geometry"><rect><x>0</x><y>20</y><width>341</width><height>451</height></rect></property><layout class="QFormLayout" name="formLayout"><item row="0" column="0"><widget class="QLabel" name="label_2"><property name="text"><string>发送数据</string></property></widget></item><item row="1" column="0" colspan="2"><widget class="QTextEdit" name="textEdit_send"/></item><item row="2" column="0"><widget class="QLabel" name="label"><property name="text"><string>接收数据</string></property></widget></item><item row="3" column="0" colspan="2"><widget class="QTextEdit" name="textEdit_recv"><property name="readOnly"><bool>true</bool></property></widget></item><item row="4" column="0" colspan="2"><layout class="QHBoxLayout" name="horizontalLayout_2"><item><spacer name="horizontalSpacer"><property name="orientation"><enum>Qt::Horizontal</enum></property><property name="sizeHint" stdset="0"><size><width>40</width><height>20</height></size></property></spacer></item><item><widget class="QPushButton" name="send_Bt"><property name="text"><string>发送数据</string></property></widget></item><item><spacer name="horizontalSpacer_2"><property name="orientation"><enum>Qt::Horizontal</enum></property><property name="sizeHint" stdset="0"><size><width>40</width><height>20</height></size></property></spacer></item><item><widget class="QPushButton" name="clear_send_Bt"><property name="text"><string>清空发送区</string></property></widget></item><item><spacer name="horizontalSpacer_4"><property name="orientation"><enum>Qt::Horizontal</enum></property><property name="sizeHint" stdset="0"><size><width>40</width><height>20</height></size></property></spacer></item></layout></item></layout></widget></widget><widget class="QGroupBox" name="groupBox"><property name="geometry"><rect><x>10</x><y>10</y><width>191</width><height>311</height></rect></property><property name="title"><string>串口配置</string></property><widget class="QWidget" name="gridLayoutWidget_2"><property name="geometry"><rect><x>10</x><y>20</y><width>169</width><height>281</height></rect></property><layout class="QGridLayout" name="gridLayout_2"><item row="1" column="0"><spacer name="verticalSpacer"><property name="orientation"><enum>Qt::Vertical</enum></property><property name="sizeHint" stdset="0"><size><width>20</width><height>40</height></size></property></spacer></item><item row="2" column="0"><widget class="QPushButton" name="Serial_check_Bt"><property name="minimumSize"><size><width>93</width><height>28</height></size></property><property name="text"><string>检测串口</string></property></widget></item><item row="3" column="0"><widget class="QPushButton" name="open_serial_Bt"><property name="minimumSize"><size><width>93</width><height>28</height></size></property><property name="text"><string>打开串口</string></property></widget></item><item row="0" column="0"><layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,0" columnstretch="0,0"><property name="sizeConstraint"><enum>QLayout::SetDefaultConstraint</enum></property><property name="leftMargin"><number>0</number></property><property name="topMargin"><number>0</number></property><property name="rightMargin"><number>0</number></property><property name="bottomMargin"><number>0</number></property><property name="horizontalSpacing"><number>6</number></property><property name="verticalSpacing"><number>0</number></property><item row="3" column="0"><widget class="QLabel" name="label_databit"><property name="minimumSize"><size><width>72</width><height>30</height></size></property><property name="maximumSize"><size><width>76</width><height>30</height></size></property><property name="text"><string>数据位:</string></property></widget></item><item row="4" column="0"><widget class="QLabel" name="label_parity"><property name="minimumSize"><size><width>72</width><height>30</height></size></property><property name="maximumSize"><size><width>76</width><height>30</height></size></property><property name="text"><string>校验位:</string></property></widget></item><item row="1" column="1"><widget class="QComboBox" name="serial_Cb"><property name="minimumSize"><size><width>87</width><height>22</height></size></property><property name="maximumSize"><size><width>76</width><height>15</height></size></property></widget></item><item row="5" column="0"><widget class="QLabel" name="label_stopbit"><property name="minimumSize"><size><width>72</width><height>30</height></size></property><property name="maximumSize"><size><width>76</width><height>30</height></size></property><property name="text"><string>停止位:</string></property></widget></item><item row="5" column="1"><widget class="QComboBox" name="stopbit_Cb"><property name="minimumSize"><size><width>87</width><height>22</height></size></property><property name="maximumSize"><size><width>76</width><height>15</height></size></property><item><property name="text"><string>none</string></property></item><item><property name="text"><string>奇校验</string></property></item><item><property name="text"><string>偶校验</string></property></item></widget></item><item row="4" column="1"><widget class="QComboBox" name="checkbit_Cb"><property name="minimumSize"><size><width>87</width><height>22</height></size></property><property name="maximumSize"><size><width>76</width><height>15</height></size></property><item><property name="text"><string>1</string></property></item><item><property name="text"><string>1.5</string></property></item><item><property name="text"><string>2</string></property></item></widget></item><item row="2" column="1"><widget class="QComboBox" name="baundrate_Cb"><property name="minimumSize"><size><width>87</width><height>22</height></size></property><property name="maximumSize"><size><width>76</width><height>15</height></size></property><property name="currentText"><string>9600</string></property><property name="currentIndex"><number>3</number></property><item><property name="text"><string>1200</string></property></item><item><property name="text"><string>2400</string></property></item><item><property name="text"><string>4800</string></property></item><item><property name="text"><string>9600</string></property></item><item><property name="text"><string>19200</string></property></item><item><property name="text"><string>38400</string></property></item><item><property name="text"><string>57600</string></property></item><item><property name="text"><string>115200</string></property></item></widget></item><item row="1" column="0"><widget class="QLabel" name="label_serialport"><property name="minimumSize"><size><width>72</width><height>30</height></size></property><property name="maximumSize"><size><width>76</width><height>30</height></size></property><property name="text"><string>端口号:</string></property></widget></item><item row="2" column="0"><widget class="QLabel" name="label_baudrate"><property name="minimumSize"><size><width>72</width><height>30</height></size></property><property name="maximumSize"><size><width>76</width><height>30</height></size></property><property name="text"><string>波特率:</string></property></widget></item><item row="3" column="1"><widget class="QComboBox" name="databit_Cb"><property name="minimumSize"><size><width>87</width><height>22</height></size></property><property name="maximumSize"><size><width>76</width><height>15</height></size></property><property name="currentText"><string>8</string></property><item><property name="text"><string>8</string></property></item><item><property name="text"><string>7</string></property></item><item><property name="text"><string>6</string></property></item><item><property name="text"><string>5</string></property></item></widget></item></layout></item></layout></widget></widget><widget class="QGroupBox" name="groupBox_2"><property name="geometry"><rect><x>10</x><y>330</y><width>191</width><height>81</height></rect></property><property name="title"><string>接收设置</string></property><widget class="QWidget" name="formLayoutWidget_2"><property name="geometry"><rect><x>10</x><y>20</y><width>189</width><height>56</height></rect></property><layout class="QFormLayout" name="formLayout_2"><item row="0" column="0"><widget class="QPushButton" name="clear_recv_Bt"><property name="text"><string>清空接收</string></property></widget></item><item row="0" column="1"><widget class="QCheckBox" name="recv_hex_Chb"><property name="text"><string>Hex接收</string></property></widget></item><item row="1" column="0"><widget class="QCheckBox" name="recv_time_Chb"><property name="text"><string>时间戳</string></property></widget></item><item row="1" column="1"><widget class="QCheckBox" name="recv_autoline_Chb"><property name="text"><string>自动换行</string></property></widget></item></layout></widget></widget><widget class="QGroupBox" name="groupBox_3"><property name="geometry"><rect><x>10</x><y>420</y><width>191</width><height>71</height></rect></property><property name="title"><string>发送设置</string></property><widget class="QWidget" name="layoutWidget"><property name="geometry"><rect><x>10</x><y>20</y><width>183</width><height>49</height></rect></property><layout class="QGridLayout" name="gridLayout_5"><item row="0" column="0"><widget class="QCheckBox" name="send_hex_Chb"><property name="text"><string>Hex发送</string></property></widget></item><item row="0" column="1" colspan="2"><widget class="QCheckBox" name="send_line_Chb"><property name="text"><string>发送新行</string></property></widget></item><item row="1" column="0"><widget class="QCheckBox" name="autosend_Chb"><property name="text"><string>自动发送</string></property></widget></item><item row="1" column="1"><widget class="QSpinBox" name="txtSendMs"><property name="minimumSize"><size><width>60</width><height>0</height></size></property><property name="readOnly"><bool>false</bool></property></widget></item><item row="1" column="2"><widget class="QLabel" name="label_3"><property name="text"><string>ms</string></property></widget></item></layout></widget></widget></widget><widget class="QStatusBar" name="statusbar"/><widget class="QMenuBar" name="menuBar"><property name="geometry"><rect><x>0</x><y>0</y><width>578</width><height>23</height></rect></property><widget class="QMenu" name="menu"><property name="title"><string>串口工具</string></property></widget><widget class="QMenu" name="menuTCP"><property name="title"><string>TCP工具</string></property></widget><widget class="QMenu" name="menuUDP"><property name="title"><string>UDP工具</string></property></widget><widget class="QMenu" name="menuCAN"><property name="title"><string>CAN工具</string></property></widget><widget class="QMenu" name="menu_2"><property name="title"><string>画图工具</string></property></widget><addaction name="menu"/><addaction name="menuTCP"/><addaction name="menuUDP"/><addaction name="menuCAN"/><addaction name="menu_2"/></widget></widget><resources/><connections/>
</ui>

4. 实现登录逻辑

main.cpp主程序进入界面

#include "mainwindow.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}

在对应的mainwindow.cpp文件中实现登录逻辑:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "serial.h"
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), settings(new QSettings("YourCompany", "YourApp")), ui(new Ui::MainWindow)
{ui->setupUi(this);// 设置背景图片QFile file(":/ship.png"); // 如果使用资源系统,请根据实际情况调整路径if(file.exists()) {this->setStyleSheet("MainWindow { background-image: url(:/ship.png)};");} else{qDebug() << "Background image not found!";}//隐匿密码ui->password->setEchoMode(QLineEdit::Password);//登录按钮connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::login);//按钮传参显示密码按钮connect(ui->radioButton, &QPushButton::clicked, this, &MainWindow::display_psd);// 记住密码复选框connect(ui->checkBox, &QCheckBox::stateChanged, this, &MainWindow::saveSettings);loadSettings();
}MainWindow::~MainWindow()
{delete ui;delete settings;
}void MainWindow::login()
{saveSettings();QString nameString = ui->accout->text();QString pswdString = ui->password->text();// 检查用户名和密码是否匹配if ((nameString == QString::fromLocal8Bit("admin") && pswdString == QString::fromLocal8Bit("123456")) ||(nameString == QString::fromLocal8Bit("user") && pswdString == QString::fromLocal8Bit("111111"))) {Serial* w = new Serial(); // 使用 'this' 作为父对象,Qt 会自动管理其生命周期qDebug() << "Creating Software instance.";this->close();w->show();} else{QMessageBox::about(this, "警告", "用户名或密码错误");}
}void MainWindow::display_psd(bool checked)
{if (checked) {//显示密码ui->password->setEchoMode(QLineEdit::Normal);}else {//密文显示ui->password->setEchoMode(QLineEdit::Password);}
}void MainWindow::saveSettings()
{bool remember = ui->checkBox->isChecked();QString username = ui->accout->text();QString password = ui->password->text();settings->setValue("remember", remember);if (remember) {settings->setValue("username", username);settings->setValue("password", password);} else {settings->remove("username");settings->remove("password");}
}
void MainWindow::loadSettings()
{bool remember = settings->value("remember", false).toBool();QString username = settings->value("username", "").toString();QString password = settings->value("password", "").toString();ui->checkBox->setChecked(remember);ui->accout->setText(username);ui->password->setText(password);
}

这段代码实现了一个简单的登录窗口,具备记住密码、显示/隐藏密码和基本的用户验证功能。以下是各部分的功能概述:

  1. 构造函数 MainWindow::MainWindow

    • 初始化主窗口,设置背景图片(如果存在),并初始化一些UI元素。
    • 为密码输入框设置密码模式(即隐藏输入字符)。
    • 连接按钮和复选框到相应的槽函数,以便处理用户的交互操作。
    • 调用 loadSettings() 函数加载上次保存的设置。
  2. 析构函数 MainWindow::~MainWindow

    • 清理资源,包括删除UI对象和设置对象。
  3. login 函数

    • 验证用户名和密码是否正确。如果匹配,则关闭当前登录窗口,并打开一个新的 Serial 窗口。
    • 如果不匹配,弹出一个警告消息框提示用户名或密码错误。
  4. display_psd 函数

    • 根据复选框的状态切换密码输入框的显示模式:如果选中则显示密码文本,否则隐藏(以圆点形式显示)。
  5. saveSettingsloadSettings 函数

    • saveSettings:根据复选框状态决定是否保存用户名和密码。如果用户选择了“记住密码”,则将这些信息保存到应用设置中;否则,从设置中移除这些信息。
    • loadSettings:在启动时读取保存的设置,并根据这些设置更新UI组件(例如,自动填写用户名和密码,以及勾选“记住密码”复选框)。

整体来说,这段代码主要实现了以下功能:

  • 提供了一个图形界面用于用户登录。
  • 支持记住用户凭据的功能,方便用户下次登录。
  • 提供了显示/隐藏密码选项,增加了用户体验。
  • 在验证用户身份后,可以跳转到另一个应用界面(Serial 窗口)。

请注意,直接存储密码的做法存在安全风险,在实际应用中应采用更安全的方式处理用户认证信息。
mainwindow.h预定义槽函数,导入QT相关的库

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QMessageBox>
#include <QSettings>
#include <QFile>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();QSettings *settings;private slots:void login();void saveSettings();void loadSettings();void display_psd(bool checked);private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

5.串口界面

serial.h预定义串口相关功能函数,导入串口的库文件

#ifndef SERIAL_H
#define SERIAL_H#include <QMainWindow>
#include <QSerialPort>
#include <QString>
#include <QSerialPortInfo>
#include <QMessageBox>
#include <QTimer>
#include <QTime>
#include <QPainter>
#include <QDebug>
namespace Ui {
class Serial;
}class Serial : public QMainWindow
{Q_OBJECTpublic:explicit Serial(QWidget *parent = nullptr);~Serial();QSerialPort *serialPort;//定义串口指针private slots://    void on_button_openserial_clicked();/*手动连接槽函数*/void manual_serialPortReadyRead();void on_chkTimSend_stateChanged(int arg1);/*以下为mainwindow.ui文件中点击“转到槽”自动生成的函数*/void on_Serial_check_Bt_clicked();void on_open_serial_Bt_clicked();void on_send_Bt_clicked();void on_clear_recv_Bt_clicked();void on_clear_send_Bt_clicked();
private:Ui::Serial *ui;// 发送、接收字节计数long sendNum, recvNum;QLabel *lblSendNum;QLabel *lblRecvNum;QLabel *lblPortState;void setNumOnLabel(QLabel *lbl, QString strS, long num);// 定时发送-定时器QTimer *timSend;};#endif // SERIAL_H

serial.cpp实现定义串口相关功能函数

#include "serial.h"
#include "ui_serial.h"
#include "QSerialPortInfo"
#include <QSerialPort>
#include <QMessageBox>
#include <QDateTime>
#include <QStatusBar>
Serial::Serial(QWidget *parent) :QMainWindow(parent),ui(new Ui::Serial)
{ui->setupUi(this);QStringList serialNamePort;serialPort = new QSerialPort(this);connect(serialPort,SIGNAL(readyRead()),this,SLOT(manual_serialPortReadyRead()));/*手动连接槽函数*//*找出当前连接的串口并显示到serailCb*/on_Serial_check_Bt_clicked();// 发送、接收计数清零sendNum = 0;recvNum = 0;// 状态栏QStatusBar *sBar = statusBar();// 状态栏的收、发计数标签lblSendNum = new QLabel(this);lblRecvNum = new QLabel(this);lblPortState = new QLabel(this);lblPortState->setText("Connected");//设置串口状态标签为绿色 表示已连接状态lblPortState->setStyleSheet("color:red");// 设置标签最小大小lblSendNum->setMinimumSize(100, 20);lblRecvNum->setMinimumSize(100, 20);lblPortState->setMinimumSize(550, 20);setNumOnLabel(lblSendNum, "S: ", sendNum);setNumOnLabel(lblRecvNum, "R: ", recvNum);// 从右往左依次添加sBar->addPermanentWidget(lblPortState);sBar->addPermanentWidget(lblSendNum);sBar->addPermanentWidget(lblRecvNum);// 定时发送-定时器timSend = new QTimer;timSend->setInterval(1000);// 设置默认定时时长1000msconnect(timSend, &QTimer::timeout, this, [=](){on_send_Bt_clicked();});}Serial::~Serial()
{if(ui != nullptr){delete ui;delete serialPort;delete timSend;delete lblSendNum;delete lblRecvNum;delete lblPortState;}}void Serial::on_Serial_check_Bt_clicked()
{ui->serial_Cb->clear();//通过QSerialPortInfo查找可用串口foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){ui->serial_Cb->addItem(info.portName());}}void Serial::on_open_serial_Bt_clicked()
{/*串口初始化*/QSerialPort::BaudRate baudRate;QSerialPort::DataBits dataBits;QSerialPort::StopBits stopBits;QSerialPort::Parity checkBits;baudRate=QSerialPort::Baud9600;dataBits=QSerialPort::Data8;stopBits=QSerialPort::OneStop;checkBits = QSerialPort::NoParity;// 获取串口波特率// baudRate = ui->baundrate_Cb->currentText().toInt();直接字符串转换为 int 的方法if(ui->baundrate_Cb->currentText()=="1200")baudRate=QSerialPort::Baud1200;else if(ui->baundrate_Cb->currentText()=="2400")baudRate=QSerialPort::Baud2400;else if(ui->baundrate_Cb->currentText()=="4800")baudRate=QSerialPort::Baud4800;else if(ui->baundrate_Cb->currentText()=="9600")baudRate=QSerialPort::Baud9600;else if(ui->baundrate_Cb->currentText()=="19200")baudRate=QSerialPort::Baud19200;else if(ui->baundrate_Cb->currentText()=="38400")baudRate=QSerialPort::Baud38400;else if(ui->baundrate_Cb->currentText()=="57600")baudRate=QSerialPort::Baud57600;else if(ui->baundrate_Cb->currentText()=="115200")baudRate=QSerialPort::Baud115200;// 获取串口数据位if(ui->databit_Cb->currentText()=="5")dataBits=QSerialPort::Data5;else if(ui->databit_Cb->currentText()=="6")dataBits=QSerialPort::Data6;else if(ui->databit_Cb->currentText()=="7")dataBits=QSerialPort::Data7;else if(ui->databit_Cb->currentText()=="8")dataBits=QSerialPort::Data8;// 获取串口停止位if(ui->stopbit_Cb->currentText()=="1")stopBits=QSerialPort::OneStop;else if(ui->stopbit_Cb->currentText()=="1.5")stopBits=QSerialPort::OneAndHalfStop;else if(ui->stopbit_Cb->currentText()=="2")stopBits=QSerialPort::TwoStop;// 获取串口奇偶校验位if(ui->checkbit_Cb->currentText() == "none"){checkBits = QSerialPort::NoParity;}else if(ui->checkbit_Cb->currentText() == "奇校验"){checkBits = QSerialPort::OddParity;}else if(ui->checkbit_Cb->currentText() == "偶校验"){checkBits = QSerialPort::EvenParity;}// 初始化串口属性,设置 端口号、波特率、数据位、停止位、奇偶校验位数serialPort->setPortName(ui->serial_Cb->currentText());serialPort->setBaudRate(baudRate);serialPort->setDataBits(dataBits);serialPort->setStopBits(stopBits);serialPort->setParity(checkBits);// 根据初始化好的串口属性,打开串口// 如果打开成功,反转打开按钮显示和功能。打开失败,无变化,并且弹出错误对话框。if(ui->open_serial_Bt->text() == "打开串口"){if(serialPort->open(QIODevice::ReadWrite) == true){//QMessageBox::ui->open_serial_Bt->setText("关闭串口");// 让端口号下拉框不可选,避免误操作(选择功能不可用,控件背景为灰色)ui->serial_Cb->setEnabled(false);}else{QMessageBox::critical(this, "错误提示", "串口打开失败!!!\r\n该串口可能被占用\r\n请选择正确的串口");}//statusBar 状态栏显示端口状态QString sm = "%1 OPENED, %2, 8, NONE, 1";QString status = sm.arg(serialPort->portName()).arg(serialPort->baudRate());lblPortState->setText(status);lblPortState->setStyleSheet("color:green");}else{serialPort->close();ui->open_serial_Bt->setText("打开串口");// 端口号下拉框恢复可选,避免误操作ui->serial_Cb->setEnabled(true);//statusBar 状态栏显示端口状态QString sm = "%1 CLOSED";QString status = sm.arg(serialPort->portName());lblPortState->setText(status);lblPortState->setStyleSheet("color:red");}}void Serial::on_send_Bt_clicked()
{QByteArray array;//Hex复选框if(ui->send_hex_Chb->checkState() == Qt::Checked){//array = QString2Hex(data);  //HEX 16进制array = QByteArray::fromHex(ui->textEdit_send->toPlainText().toUtf8()).data();}else{//array = data.toLatin1();    //ASCIIarray = ui->textEdit_send->toPlainText().toLocal8Bit().data();}if(ui->send_line_Chb->checkState() == Qt::Checked){array.append("\r\n");}// 如发送成功,会返回发送的字节长度。失败,返回-1。int a = serialPort->write(array);// 发送字节计数并显示if(a > 0){// 发送字节计数sendNum += a;// 状态栏显示计数值setNumOnLabel(lblSendNum, "S: ", sendNum);}
}void Serial::on_clear_recv_Bt_clicked()
{ui->textEdit_recv->clear();// 清除接收字节计数sendNum = 0;// 状态栏显示计数值setNumOnLabel(lblSendNum, "S: ", sendNum);
}void Serial::on_clear_send_Bt_clicked()
{ui->textEdit_send->clear();// 清除发送字节计数sendNum = 0;// 状态栏显示计数值setNumOnLabel(lblSendNum, "S: ", sendNum);
}// 定时发送开关 选择复选框
void Serial::on_chkTimSend_stateChanged(int arg1)
{// 获取复选框状态,未选为0,选中为2if(arg1 == 0){timSend->stop();// 时间输入框恢复可选ui->txtSendMs->setEnabled(true);}else{// 对输入的值做限幅,小于10ms会弹出对话框提示if(ui->txtSendMs->text().toInt() >= 10){timSend->start(ui->txtSendMs->text().toInt());// 设置定时时长,重新计数// 让时间输入框不可选,避免误操作(输入功能不可用,控件背景为灰色)ui->txtSendMs->setEnabled(false);}else{ui->autosend_Chb->setCheckState(Qt::Unchecked);QMessageBox::critical(this, "错误提示", "定时发送的最小间隔为 10ms\r\n请确保输入的值 >=10");}}
}/*手动实现接收数据函数*/
void Serial::manual_serialPortReadyRead()
{QByteArray recBuf = serialPort->readAll();QString str_rev;// 接收字节计数recvNum += recBuf.size();// 状态栏显示计数值setNumOnLabel(lblRecvNum, "R: ", recvNum);if(ui->recv_hex_Chb->checkState() == false){if(ui->recv_time_Chb->checkState() == Qt::Checked){QDateTime nowtime = QDateTime::currentDateTime();str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";str_rev += QString(recBuf).append("\r\n");}else{// 在当前位置插入文本,不会发生换行。如果没有移动光标到文件结尾,会导致文件超出当前界面显示范围,界面也不会向下滚动。//ui->recvEdit->appendPlainText(buf);if(ui->recv_autoline_Chb->checkState() == Qt::Checked){str_rev = QString(recBuf).append("\r\n");}else{str_rev = QString(recBuf);}}}else{// 16进制显示,并转换为大写QString str1 = recBuf.toHex().toUpper();//.data();// 添加空格QString str2;for(int i = 0; i<str1.length (); i+=2){str2 += str1.midRef (i,2);str2 += " ";}if(ui->recv_time_Chb->checkState() == Qt::Checked){QDateTime nowtime = QDateTime::currentDateTime();str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";str_rev += str2.append("\r\n");}else{if(ui->recv_autoline_Chb->checkState() == Qt::Checked)str_rev += str2.append("\r\n");elsestr_rev = str2;}}ui->textEdit_recv->insertPlainText(str_rev);ui->textEdit_recv->moveCursor(QTextCursor::End);}// 状态栏标签显示计数值
void Serial::setNumOnLabel(QLabel *lbl, QString strS, long num)
{// 标签显示QString strN;strN.sprintf("%ld", num);QString str = strS + strN;lbl->setText(str);
}

6.测试功能

在这里插入图片描述
运行此代码,弹出登录界面
在这里插入图片描述

输入用户密码
admin123456
user111111

这里有两个账号,点击记住密码,下次就可以不输入密码直接登录就接入串口界面
在这里插入图片描述

在这里插入图片描述
然后配置串口参数打开串口,这就可以正常收发啦!

7.总结

以上就是使用Qt实现基本的用户登录以及界面跳转的过程。实际开发过程中,你可能还需要考虑更多细节,比如数据加密存储、网络通信安全等。此外,对于多窗口的应用程序,良好的架构设计有助于管理不同窗口之间的交互和状态维护。
🛹🛹🛹从而实现对外部世界进行感知,充分认识这个有机与无机的环境🥳🥳🥳科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力。🤣🤣🤣

如果你有任何问题,可以通过下面的二维码加入鹏鹏小分队,期待与你思维的碰撞😘😘😘

参考文献:
相关好文推荐:

  1. QT初体验:手把手带你写一个自己的串口助手
  2. 【Qt安装与简易串口控制Arduino开发板小灯教程】
  3. 【QT串口助手】

相关文章:

【QT用户登录与界面跳转】

【QT用户登录与界面跳转】 1.前言2. 项目设置3.设计登录界面3.1 login.pro参数3.2 界面设置3.2.1 登录界面3.2.2 串口主界面 4. 实现登录逻辑5.串口界面6.测试功能7.总结 1.前言 在Qt应用程序开发中&#xff0c;实现用户登录及界面跳转功能是构建交互式应用的重要步骤之一。下…...

【docker踩坑记录】

docker踩坑记录 踩坑记录(持续更新中.......)docker images 权限问题 踩坑记录(持续更新中…) docker images 权限问题 permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Head "http://%2Fvar%2Frun%2Fdocker.s…...

【Azure 架构师学习笔记】- Azure Function (2) --实操1

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Function 】系列。 接上文【Azure 架构师学习笔记】- Azure Function (1) --环境搭建和背景介绍 前言 上一文介绍了环境搭建&#xff0c;接下来就在本地环境下使用一下。 环境准备 这里我下载了最新的VS studio&…...

豆包MarsCode:构造特定数组的逆序拼接

问题描述 思路分析 1. 数组的组成&#xff1a; 我们要根据 i 的不同值拼接出不同长度的子数组。对于每个 i 从 1 到 n&#xff0c;我们要把数字从 n 逆序到 i 拼接成一个子数组。 例如&#xff0c;当 i 1 时&#xff0c;拼接 [n, n-1, ..., 1]。当 i 2 时&#xff0c;拼接 …...

14-美妆数据分析

前言 美妆数据分析可以帮助企业更好地理解市场趋势、客户偏好和产品表现 import pandas as pd import numpy as np 一、数据清洗 data pd.read_csv(rC:\Users\B\Desktop\美妆数据.csv,encodinggbk) data.head()data.info()data data.drop_duplicates(inplaceFalse) data.r…...

新阿里云买服务器配置需手动配置80端口

新买阿里云服务器需手动配置80&#xff0c;端口才可以访问nginx CentOS系统 安装nginx 1. 安装 Nginx yum install nginx 2. 启动 Nginx 服务 systemctl start nginx 3. 修改默认网页 cd /usr/share/nginx/ echo "666" >index.html cat index.html 访问ngin最后…...

Mysql--实战篇--连接泄漏问题(什么是连接泄漏,未关闭SqlSession,长事务处理,连接池管理等)

1、什么是连接泄漏&#xff08;Connection Leak&#xff09;&#xff1f; 连接泄漏是指应用程序未能正确关闭数据库连接&#xff0c;导致连接池中的可用连接逐渐减少&#xff0c;最终耗尽所有连接。连接泄漏可能会导致新的请求无法获得连接&#xff0c;进而引发服务中断。 连…...

【ESP32】ESP-IDF开发 | WiFi开发 | AP模式 + 基站连接例程

1. 简介 前面一篇讲了WiFi的基站模式&#xff0c;演示了怎么编程连接AP&#xff0c;所以这一篇讲一讲AP模式&#xff0c;ESP32作AP&#xff0c;让其他的设备连接自己。 1.1 DHCP 这里需要补充一个知识点——DHCP服务器。当基站连接一个AP时&#xff0c;会被分配一个IP&#xf…...

Ubuntu升级Linux内核教程

本文作者CVE-柠檬i: CVE-柠檬i-CSDN博客 本文使用的方法是dpkg安装&#xff0c;目前版本为5.4.0-204&#xff0c;要升级成5.8.5版本 下载 下载网站&#xff1a;https://kernel.ubuntu.com/mainline/ 在该网站下载deb包&#xff0c;选择自己想要升级的版本&#xff0c;这里是5…...

关于AWS网络架构的思考

目录&#xff1a; AWS概述 EMR Serverless AWS VPC及其网络 关于AWS网络架构的思考 在AWS K8S中部署的业务&#xff0c;有不同的流量路径。 流量进入 客户端请求 普通的客户端流量流向从前到后是: 客户端公司网关(endpoint)业务的Endpoint ServiceLoad Balancers(监听80和…...

Pandas库的常用内容归纳

Pandas 是一个强大的 Python 数据分析库&#xff0c;提供了大量用于数据处理和分析的功能。以下是一些 Pandas 库中常用的功能&#xff1a; 数据创建和操作 Series 和 DataFrame&#xff1a;创建一维的 Series 和二维的 DataFrame 对象。数据导入&#xff1a;从 CSV、Excel、…...

【错误解决方案记录】spine3.8.75导出的数据使用unity-spine3.8插件解析失败报错的解决方案

报错信息 Exception: Unsupported skeleton data, please export with a newer version of Spine. Spine.SkeletonBinary.ReadSkeletonData (System.IO.Stream file) (at Assets/Spine/Runtime/spine-csharp/SkeletonBinary.cs:132) Spine.Unity.Editor.AssetUtility.AddRequi…...

Python与PyTorch的浅拷贝与深拷贝

1.Python赋值操作的原理 在python中&#xff0c;x something&#xff0c; 这样的赋值操作&#xff0c;准确的理解是&#xff1a;给存储something建立一个索引x (即存储地址)&#xff0c; x通过访问something的存储内容&#xff0c;获得something的值。 在下面代码中&#xff…...

【unity进阶篇】弧度、角度和三角函数(Mathf),并实现类似蛇的运动

考虑到每个人基础可能不一样&#xff0c;且并不是所有人都有同时做2D、3D开发的需求&#xff0c;所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】&#xff1a;主要讲解C#的基础语法&#xff0c;包括变量、数据类型、运算符、…...

【分类】【损失函数】处理类别不平衡:CEFL 和 CEFL2 损失函数的实现与应用

引言 在深度学习中的分类问题中&#xff0c;类别不平衡问题是常见的挑战之一。尤其在面部表情分类任务中&#xff0c;不同表情类别的样本数量可能差异较大&#xff0c;比如“开心”表情的样本远远多于“生气”表情。面对这种情况&#xff0c;普通的交叉熵损失函数容易导致模型…...

支持selenium的chrome driver更新到132.0.6834.83

最近chrome释放新版本&#xff1a;132.0.6834.83 如果运行selenium自动化测试出现以下问题&#xff0c;是需要升级chromedriver才可以解决的。 selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only su…...

IO模型与NIO基础二

抽象基类之二 FilterInputStream FilterInputStream 的作用是用来“封装其它的输入流&#xff0c;并为它们提供额外的功能”。 它的常用的子类有BufferedInputStream和DataInputStream。 (1) BufferedInputStream的作用就是为“输入流提供缓冲功能&#xff0c;以及mark()和res…...

什么是FPGA开发?

FPGA&#xff08;Field-Programmable Gate Array&#xff09;&#xff0c;即现场可编程门阵列&#xff0c;是一种通过编程方式实现特定功能的集成电路。与传统的ASIC&#xff08;专用集成电路&#xff09;相比&#xff0c;FPGA具有灵活性高、开发周期短、成本相对较低等优势&am…...

寻找川味:成都九尺板鸭

寻找川味:成都九尺板鸭 在四川这片美食的天堂里,隐藏着无数令人垂涎的传统名吃。其中,成都九尺板鸭以其悠久的历史、独特的制作工艺和令人难以抗拒的美味,成为了许多食客心中不可错过的地道川味。 历史渊源 九尺板鸭,顾名思义,因主产于四川省成都市彭州市九尺镇而得名。早在5…...

Object常用的方法及开发中的使用场景

在前端开发中&#xff0c;Object 对象提供了许多常用的方法&#xff0c;这些方法帮助我们操作对象的属性和结构。以下是常用的 Object 方法及其功能简要说明&#xff1a; 对象常用的方法 1. 创建对象 Object.create(proto[, propertiesObject]) 创建一个具有指定原型对象和属性…...

ElasticSearch上

安装ElasticSearch Lucene&#xff1a;Java语言的搜索引擎类库&#xff0c;易扩展&#xff1b;高性能&#xff08;基于倒排索引&#xff09;Elasticsearch基于Lucene&#xff0c;支持分布式&#xff0c;可水平扩展&#xff1b;提供Restful接口&#xff0c;可被任何语言调用Ela…...

基于SpringCloud的广告系统设计与实现(二)

一、common公共模块 1.common的作用 通用的代码、配置不应该散落在各个业务模块中&#xff0c;不利于维护与更新 一个大的系统&#xff0c;响应对象需要统一外层格式 各种业务设计与实现&#xff0c;可能会抛出各种各样的异常&#xff0c;异常信息的收集也应该做到统一 2.统…...

2011年西部数学奥林匹克的几何题

2011G1 证明: 显然, O O O, I I I, F F F 共线, E I / / M O EI//MO EI//MO, △ E I F ∼ △ M O F \triangle EIF \sim \triangle MOF △EIF∼△MOF. 进而 E F / M F r 1 / r 2 EF/MFr_1/r_2 EF/MFr1​/r2​. ( r 1 (r_1 (r1​ 为圆 I I I 的半径, r 2 r_2 r2​ 为…...

(一)afsim第三方库编译

注意&#xff1a;防止奇怪的问题&#xff0c;源码编译的路径最好不要有中文&#xff0c;请先检查各文件夹名 AFSIM版本 Version&#xff1a; 2.9 Plugin API Version&#xff1a; 11 软件环境 操作系统&#xff1a; Kylin V10 SP1 项目构建工具: cmake-3.26.0-linux-aarch6…...

boss直聘 __zp_stoken__ 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向过程 py代码 import execjs imp…...

python matplotlib绘图,显示和保存没有标题栏和菜单栏的图像

目录 1. 使用plt.savefig保存无边框图形 2. 显示在屏幕上&#xff0c;并且去掉窗口的标题栏和工具栏 3. 通过配置 matplotlib 的 backend 和使用 Tkinter&#xff08;或其他图形库&#xff09; 方法 1&#xff1a;使用 TkAgg 后端&#xff0c;并禁用窗口的工具栏和标题栏 …...

AI-Talk开发板之替换唤醒词

一、说明 聆思提供的Demo唤醒词默认为"小美,小美"&#xff0c;V2.4及之后的SDK支持替换唤醒词&#xff0c;聆思提供了在线工具生成唤醒词固件。 工具&#xff1a;tool.listenai.com/audio-custom/products/ 官方博客教程&#xff1a;实操给桌面AI语音助理&#xff…...

C#实现字符串反转的4种方法

见过不少人、经过不少事、也吃过不少苦&#xff0c;感悟世事无常、人心多变&#xff0c;靠着回忆将往事串珠成链&#xff0c;聊聊感情、谈谈发展&#xff0c;我慢慢写、你一点一点看...... 1、string.Reverse 方法 string content "Hello World";string reverseStri…...

【MySQL索引:B+树与页的深度解析】

文章目录 MySQL索引&#xff1a;B树与页的深度解析1. 索引使用的数据结构——B树1.1 B树介绍1.2 B树的特点1.3 B树和B树的对比 2. MySQL中的页2.1 页的介绍2.2 页主体2.3 页目录2.4 B树在MySQL索引中的应用 MySQL索引&#xff1a;B树与页的深度解析 在MySQL数据库中&#xff0…...

在 macOS 上,用命令行连接 MySQL(/usr/local/mysql/bin/mysql -u root -p)

根据你提供的文件内容&#xff0c;MySQL 的安装路径是 /usr/local/mysql。要直接使用 mysql 命令&#xff0c;你需要找到 mysql 可执行文件的路径。 在 macOS 上&#xff0c;mysql 客户端通常位于 MySQL 安装目录的 bin 子目录中。因此&#xff0c;完整的路径应该是&#xff1…...

深入HDFS——数据上传源码

引入 就如RPC篇章里提到的观点一样&#xff0c;任何一种能广为传播的技术&#xff0c;都是通过抽象和封装的思想&#xff0c;屏蔽底层底层复杂实现&#xff0c;提供简单且强大的工具&#xff0c;来降低使用门槛的。 HDFS的风靡自然也是如此。 通过前面深入了NameNode和DataN…...

归并排序算法

归并排序 1算法介绍 和选择排序一样&#xff0c;归并排序的性能不受输入数据的影响&#xff0c;但表现比选择排序好的多&#xff0c;因为始终都是O(n log n&#xff09;的时间复杂度。代价是需要额外的内存空间。归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用…...

优雅解决webview_flutter不支持安卓选择图片视频文件问题

这个问题&#xff0c;网上一搜索&#xff0c;就是要去修改别人写好的插件。 搞Flutter开发&#xff0c;尽量不要去修改别人的插件 &#xff0c;特别是像 webview_flutter 这种比较大的官方插件。 相信我&#xff0c;你拿捏不了它。 主要问题就是&#xff1a; webview_flutter…...

Linux UDP 编程详解

一、引言 在网络编程领域&#xff0c;UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;作为一种轻量级的传输层协议&#xff0c;具有独特的优势和适用场景。与 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff0…...

UllnnovationHub,一个开源的WPF控件库

目录 UllnnovationHub1.项目概述2.开发环境3.使用方法4.项目简介1.WPF原生控件1.Button2.GroupBox3.TabControl4.RadioButton5.SwitchButton6.TextBox7.PasswordBox8.CheckBox9.DateTimePicker10.Expander11.Card12.ListBox13.Treeview14.Combox15.Separator16.ListView17.Data…...

[Python学习日记-78] 基于 TCP 的 socket 开发项目 —— 模拟 SSH 远程执行命令

[Python学习日记-78] 基于 TCP 的 socket 开发项目 —— 模拟 SSH 远程执行命令 简介 项目分析 如何执行系统命令并拿到结果 代码实现 简介 在Python学习日记-77中我们介绍了 socket 基于 TCP 和基于 UDP 的套接字&#xff0c;还实现了服务器端和客户端的通信&#xff0c;本…...

css3过渡总结

一、过渡的定义与作用 CSS3 过渡&#xff08;Transitions&#xff09;允许 CSS 属性在一定的时间区间内平滑地过渡&#xff0c;从一个值转变为另一个值。它能够让网页元素的状态变化更加自然、流畅&#xff0c;给用户带来更好的视觉体验。例如&#xff0c;当一个元素从隐藏状态…...

生产环境中常用的设计模式

生产环境中常用的设计模式 设计模式目的使用场景示例单例模式保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点- 日志记录器- 配置管理器工厂方法模式定义一个创建对象的接口&#xff0c;让子类决定实例化哪个类- 各种工厂类&#xff08;如视频游戏工厂模式创…...

【STM32-学习笔记-4-】PWM、输入捕获(PWMI)

文章目录 1、PWMPWM配置 2、输入捕获配置3、编码器 1、PWM PWM配置 配置时基单元配置输出比较单元配置输出PWM波的端口 #include "stm32f10x.h" // Device headervoid PWM_Init(void) { //**配置输出PWM波的端口**********************************…...

游戏行业销售数据分析可视化

完整源码项目包获取→点击文章末尾名片&#xff01; &#x1f31f;分析&#xff1a; 可看出最近五年用户最喜爱的游戏类型依然还是Action-动作类&#xff08;当然市场发行的也很多&#xff09; Sports-运动类和Shooter-射击类顺序互换,但我估计现在大环境局势紧张可以会推动射击…...

微服务网关,如何选择?

什么是API网关 API网关&#xff08;API Gateway&#xff09;是微服务架构中的一个关键组件&#xff0c;它充当了客户端与后端服务之间的中间层。其主要功能包括请求路由、协议转换、负载均衡、安全认证、限流熔断等。通过API网关&#xff0c;客户端无需直接与多个微服务交互&a…...

Java开发提速秘籍:巧用Apache Commons Lang工具库

一、Java 开发效率之困 在当今数字化时代&#xff0c;Java 作为一门广泛应用的编程语言&#xff0c;在各类软件开发项目中占据着举足轻重的地位。无论是大型企业级应用、互联网平台&#xff0c;还是移动应用后端&#xff0c;都能看到 Java 的身影。然而&#xff0c;Java 开发者…...

多用户商城系统源码哪家好用?怎么选?

想拥有属于自己的多用户商城系统&#xff0c;但回头一看自己又是个技术小白&#xff0c;看着网上眼花缭乱的b2b2c商城系统&#xff0c;更是不知道如何选起&#xff1f;下面给大家分享一条较为成熟的选择思路&#xff0c;以作参考。 1、从需求上决定系统方向 企业在选型b2b2c商…...

聊聊如何实现Android 放大镜效果

一、前言 很久没有更新Android 原生技术内容了&#xff0c;前些年一直在做跨端方向开发&#xff0c;最近换工作用重新回到原生技术&#xff0c;又回到了熟悉但有些生疏的环境&#xff0c;真是感慨万分。 近期也是因为准备做地图交互相关的需求&#xff0c;功能非常复杂&#x…...

NVIDIA视频编解码

开源了两个项目&#xff1a;英伟达显卡视频编解码、jetson视频编解码。都是基于官方SDK进行的封装&#xff0c;由于官方自带的demo晦涩难懂并且每块都是独立的&#xff0c;我对SDK进行二次封装并形成了一套较为完整的视频编解码流程&#xff0c;调用简单&#xff0c;有完整的测…...

Mysql事务隔离级

什么是事务的隔离级别 数据库事务的隔离级别是指事务在并发执行时&#xff0c;如何控制事务之间相互影响的程度。它决定了多个事务并发执行时&#xff0c;事务中的操作对其他事务的可见性&#xff0c;进而影响数据的一致性和并发性。 为什么会有隔离级别的概念&#xff1f; …...

K210视觉识别模块

K210视觉识别模块是一款功能强大的AI视觉模块&#xff0c;以下是对其的详细介绍&#xff1a; 一、核心特性 强大的视觉识别功能&#xff1a;K210视觉识别模块支持多种视觉功能&#xff0c;包括但不限于人脸识别、口罩识别、条形码和二维码识别、特征检测、数字识别、颜色识别…...

springboot使用websocket

文章目录 一、概述1、简介 二、 使用1、引包2、配置处理器3、前端测试 一、概述 1、简介 简介略&#xff0c;附上官方文档&#xff0c;spring5和spring6的官方文档内容大致是一样的&#xff1a; https://docs.spring.io/spring-framework/docs/5.2.25.RELEASE/spring-framewo…...

线程池底部工作原理

线程池内部是通过线程和队列实现的&#xff0c;当我们通过线程池处理任务时&#xff1a; 如果线程池中的线程数量小于corePoolSize&#xff0c;无论是否有处于空闲的线程&#xff0c;都创建新的线程来处理被添加的任务。 如果线程池中的线程数量等于corePoolSize&#xff0c;…...

DevUI 2024 年度运营报告:开源生态的成长足迹与未来蓝图

在当今数字化飞速发展的时代&#xff0c;开源已成为推动技术创新与协作的重要力量。DevUI 作为开源领域的重要一员&#xff0c;其发展历程与成果备受关注。值此之际&#xff0c;GitCode 精心整理了 DevUI 年度运营报告&#xff0c;为您全面呈现 DevUI 社区在过去一年里的开源之…...