【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参数
- 设置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);
}
这段代码实现了一个简单的登录窗口,具备记住密码、显示/隐藏密码和基本的用户验证功能。以下是各部分的功能概述:
-
构造函数
MainWindow::MainWindow
:- 初始化主窗口,设置背景图片(如果存在),并初始化一些UI元素。
- 为密码输入框设置密码模式(即隐藏输入字符)。
- 连接按钮和复选框到相应的槽函数,以便处理用户的交互操作。
- 调用
loadSettings()
函数加载上次保存的设置。
-
析构函数
MainWindow::~MainWindow
:- 清理资源,包括删除UI对象和设置对象。
-
login
函数:- 验证用户名和密码是否正确。如果匹配,则关闭当前登录窗口,并打开一个新的
Serial
窗口。 - 如果不匹配,弹出一个警告消息框提示用户名或密码错误。
- 验证用户名和密码是否正确。如果匹配,则关闭当前登录窗口,并打开一个新的
-
display_psd
函数:- 根据复选框的状态切换密码输入框的显示模式:如果选中则显示密码文本,否则隐藏(以圆点形式显示)。
-
saveSettings
和loadSettings
函数: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.测试功能
运行此代码,弹出登录界面
输入用户 | 密码 |
---|---|
admin | 123456 |
user | 111111 |
这里有两个账号,点击记住密码,下次就可以不输入密码直接登录就接入串口界面
然后配置串口参数打开串口,这就可以正常收发啦!
7.总结
以上就是使用Qt实现基本的用户登录以及界面跳转的过程。实际开发过程中,你可能还需要考虑更多细节,比如数据加密存储、网络通信安全等。此外,对于多窗口的应用程序,良好的架构设计有助于管理不同窗口之间的交互和状态维护。
🛹🛹🛹从而实现对外部世界进行感知,充分认识这个有机与无机的环境🥳🥳🥳科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力。🤣🤣🤣
如果你有任何问题,可以通过下面的二维码加入鹏鹏小分队,期待与你思维的碰撞😘😘😘
参考文献:
相关好文推荐:
- QT初体验:手把手带你写一个自己的串口助手
- 【Qt安装与简易串口控制Arduino开发板小灯教程】
- 【QT串口助手】