【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串口助手】

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

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

相关文章

基于springboot的口腔管理平台

作者&#xff1a;学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等 文末获取“源码数据库万字文档PPT”&#xff0c;支持远程部署调试、运行安装。 项目包含&#xff1a; 完整源码数据库功能演示视频万字文档PPT 项目编码&#xff1…

4 AXI USER IP

前言 使用AXI Interface封装IP&#xff0c;并使用AXI Interface实现对IP内部寄存器进行读写实现控制LED的demo&#xff0c;这个demo是非常必要的&#xff0c;因为在前面的笔记中基本都需哟PS端与PL端就行通信互相交互&#xff0c;在PL端可以通过中断的形式来告知PS端一些事情&…

实力认证 | 海云安入选《信创安全产品及服务购买决策参考》

近日&#xff0c;国内知名安全调研机构GoUpSec发布了2024年中国网络安全行业《信创安全产品及服务购买决策参考》&#xff0c;报告从产品特点、产品优势、成功案例、安全策略等维度对各厂商信创安全产品及服务进行调研了解。 海云安凭借AI大模型技术在信创安全领域中的创新应用…

二、点灯基础实验

嵌入式基础实验第一个就是点灯&#xff0c;地位相当于编程界的hello world。 如下为LED原理图&#xff0c;要让相应LED发光&#xff0c;需要给I/O口设置输出引脚&#xff0c;低电平&#xff0c;二极管才会导通 2.1 打开初始工程&#xff0c;编写代码 以下会实现BLINKY常亮&…

Amazon MSK 开启 Public 访问 SASL 配置的方法

1. 开启 MSK Public 1.1 配置 MSK 参数 进入 MSK 控制台页面&#xff0c;点击左侧菜单 Cluster configuration。选择已有配置&#xff0c;或者创建新配置。在配置中添加参数 allow.everyone.if.no.acl.foundfalse修改集群配置&#xff0c;选择到新添加的配置。 1.2 开启 Pu…

大模型UI:Gradio全解11——Chatbot:融合大模型的聊天机器人(4)

大模型UI&#xff1a;Gradio全解11——Chatbot&#xff1a;融合大模型的聊天机器人&#xff08;4&#xff09; 前言本篇摘要11. Chatbot&#xff1a;融合大模型的多模态聊天机器人11.4 使用Blocks创建自定义聊天机器人11.4.1 简单聊天机器人演示11.4.2 立即响应和流式传输11.4.…

流量分析复现(第十八届信息安全大赛 第二届长城杯 )

zeroshell_1 题目&#xff1a;从数据包中找出攻击者利用漏洞开展攻击的会话&#xff08;攻击者执行了一条命令&#xff09;&#xff0c;写出该会话中设置的flag, 结果提交形式&#xff1a;flag{xxxxxxxxx} 这里大致的思路还是先看看&#xff0c;流量协议的分级 主要还是以TCP流…

ImportError: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32‘ not found

问题描述&#xff1a;安装MMYOLO或者MMROTATE时&#xff0c;出现的问题&#xff1a; (base) rootautodl-container-78fc438fda-4132d99a:~/autodl-tmp/MMROTATE_PROJECT/mmrotate-1.x# python demo/image_demo.py demo/demo.jpg oriented-rcnn-le90_r50_fpn_1x_dota.py orient…

2024年博客之星年度评选—创作影响力评审入围名单公布

2024年博客之星活动地址https://www.csdn.net/blogstar2024 TOP 300 榜单排名 用户昵称博客主页 身份 认证 评分 原创 博文 评分 平均 质量分评分 互动数据评分 总分排名三掌柜666三掌柜666-CSDN博客1001002001005001wkd_007wkd_007-CSDN博客1001002001005002栗筝ihttps:/…

25/1/15 嵌入式笔记 初学STM32F108

GPIO初始化函数 GPIO_Ini&#xff1a;初始化GPIO引脚的模式&#xff0c;速度和引脚号 GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化GPIOA的引脚0 GPIO输出控制函数 GPIO_SetBits&#xff1a;将指定的GPIO引脚设置为高电平 GPIO_SetBits(GPIOA, GPIO_Pin_0); // 将GPIO…

新星杯-ESP32智能硬件开发--ESP32的I/O组成-系统中断矩阵

本博文内容导读&#x1f4d5;&#x1f389;&#x1f525; ESP32开发板的中断矩阵、功能描述与实现、相关API和示例程序进行介绍 ESP32中断矩阵将任一外部中断源单独分配到每个CPU的任一外部中断上&#xff0c;提供了强大的灵活性&#xff0c;能适应不同的应用需求。 ESP32中断主…

游戏引擎学习第81天

仓库:https://gitee.com/mrxiao_com/2d_game_2 或许我们应该尝试在地面上添加一些绘图 在这段时间的工作中&#xff0c;讨论了如何改进地面渲染的问题。虽然之前并没有专注于渲染部分&#xff0c;因为当时主要的工作重心不在这里&#xff0c;但在实现过程中&#xff0c;发现地…

【2024年华为OD机试】(C卷,100分)- 悄悄话 (Java JS PythonC/C++)

一、问题描述 题目描述 给定一个二叉树&#xff0c;每个节点上站一个人&#xff0c;节点数字表示父节点到该节点传递悄悄话需要花费的时间。 初始时&#xff0c;根节点所在位置的人有一个悄悄话想要传递给其他人&#xff0c;求二叉树所有节点上的人都接收到悄悄话花费的时间…

【Spring Boot】掌握 Spring 事务:隔离级别与传播机制解读与应用

前言 &#x1f31f;&#x1f31f;本期讲解关于spring 事务传播机制介绍~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么废话…

【陕西省乡镇界】面图层shp格式arcgis数据乡镇名称和编码2020年wgs84坐标无偏移内容测评

标题中的“陕西省乡镇界面图层shp格式arcgis数据乡镇名称和编码2020年wgs84坐标无偏移.zip”表明这是一个地理信息系统&#xff08;GIS&#xff09;的数据集&#xff0c;专为陕西省的乡镇区域设计。该数据集以Shapefile&#xff08;shp&#xff09;格式提供&#xff0c;是GIS领…

国家统计局湖北调查总队副总队长张小青一行调研珈和科技农业遥感调查智能化算法

1月15日上午&#xff0c;国家统计局湖北调查总队党组成员、副总队长张小青一行莅临珈和科技开展调研。调研期间&#xff0c;张小青一行实地了解了珈和科技在自动化作物分布提取技术领域的最新成果&#xff0c;深入探讨了作物自动化处理模型在农业调查上应用的创新价值及优化方向…

-bash: /java: cannot execute binary file

在linux安装jdk报错 -bash: /java: cannot execute binary file 原因是jdk安装包和linux的不一致 程序员的面试宝典&#xff0c;一个免费的刷题平台

vue集成高德地图API实现坐标拾取功能

安装与配置&#xff1a; 组件 | vue-amapDescriptionhttps://elemefe.github.io/vue-amap/#/zh-cn/introduction/install简介 | vuemap/vue-amap简介https://vue-amap.guyixi.cn/zh-cn/introduction/introduction.html ​​​​我的应用 | 高德控制台高德开放平台官网控…

【大数据2025】Yarn 总结

分布式资源管理系统讲解总结 一、引言 围绕分布式资源管理系统展开&#xff0c;重点涵盖 Yarn 的简介、原理、资源调度策略以及运维和管理&#xff0c;旨在让学员全面掌握相关知识。Yet Another Resource Negotiator 二、Yarn 诞生背景 在 Hadoop 1.X 中仅有 HDFS 和 MapRe…

微服务学习:基础理论

一、微服务和应用现代化 1、时代的浪潮&#xff0c;企业的机遇和挑战 在互联网化数字化智能化全球化的当今社会&#xff0c;IT行业也面临新的挑战&#xff1a; 【快】业务需求如“滔滔江水连绵不绝”&#xff0c;企业需要更快的交付【变】林子大了&#xff0c;百色用户&…