项目架构
项目共有两个窗口(串口配置界面以及串口控制界面),其中包含一份项目配置文件,两份头文件,三份源文件以及两份窗口UI设计界面文件。
文件描述
- project.pro文件主要是对项目的总体配置,文件当中的
QT += core gui serialport
主要是声明在项目中用到的板块,包括图形化GUI页面设计以及串口操作板块serialport。 - 两份头文件中主要是对源文件中所用到的对象,函数包括信号与插槽进行声明和实例化。
- 源文件当中的main.cpp是整个项目的入口文件,我们在此页面实例化串口控制窗口,并进行展示。
#include "comcontroller.h"
#include <QApplication>
#include "portsettings.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ComController w;
w.show();
return a.exec();
}
- 界面文件主要包含可视化GUI页面设计,开发人员可通过图形控件的拖拽来快速的完成ui界面的模型。
开发流程
-
首先我们要完成对串口控制窗口的GUI设计,其中共用到了Push Button,Label,Group Box等组件。并通过栅栏布局将他们对齐。再对每一个控件进行对象名的修改,以便后期能够快速的区别他们。最后根据实际需求调整每一个控件的参数。
-
完成页面UI布局之后,分别为每个控件部署相应的信号与插槽。其中应保持整体的逻辑性不出现偏差(如应先连接设备后才能进行同步设备等操作。若已连接设备则应断开设备后方可再次连接)。
-
完成串口配置窗口的GUI设计,用户可以对端口号,波特率,数据位,停止位,校验位五个参数进行选择。其中端口号应由程序通过遍历查询计算机所有可用端口后,再依次加入至端口号的下拉选项当中。技术难点在于如何在当前页面选中另一页面的组件并插入内容。实现内容共分为如下几步:
- 在串口控制窗口的头文件(comcontroller.h)当中引用串口配置窗口的头文件(portsettings.h)
- 在串口配置文件的头文件中,将私有域private更改未公共域public
- 在串口控制窗口当中实例化串口配置窗口
- 通过实例化对象找到其中的ui板块以及ui当中所存在的控件
foreach (const QSerialPortInfo &Info, QSerialPortInfo::availablePorts()) {
portsettings.ui->ComboPort->addItem(Info.portName());
}
4.项目的另一难点在于如何将已配置好的串口参数传回至主窗口,然后对该串口进行数据的发送和控制。这就利用到了自定义信号与函数槽的知识点。实现过程主要分为如下几步:
- 在串口配置窗口的头文件当中定义信号和发送槽函数。
public:
explicit portSettings(QWidget *parent = 0);
~portSettings();
void changeSerialPort();
signals:
void portSignal(QString port,int baudRate,int data,int stop,int check);
- 再在串口配置窗口的源文件当中连接信号与槽函数,当用户点击确定按钮时发送串口参数。
connect(this->ui->pushButton,&QPushButton::clicked,this,&portSettings::changeSerialPort);
- 然后再实现槽函数就实现了串口参数的发送。这里的port,baudRate,data,stop,check变量是我们提前在头文件中定义过的,当下拉列表的选项发生改变时,我们可以动态的更改这些变量。
public:
Ui::portSettings *ui;
QSerialPort mSerialPort;
QString port;
int baudRate;
int data;
int stop;
int check;
void portSettings::changeSerialPort()
{
emit portSignal(port,baudRate,data,stop,check);
}
- 最后我们需要在串口控制窗口接收这些参数,再次自定义信号与槽函数(以上所有提到的槽函数均需在头文件中进行定义声明)。并在槽函数中对接收到的参数配置已经实例化过的串口实体。
connect(&portsettings,&portSettings::portSignal,this,&ComController::test);
void ComController::test(QString port,int baudRate,int data,int stop,int check){
// 设置端口号
mSerialPort.setPortName(port);
// 设置波特率
switch (baudRate) {
case 0:
mSerialPort.setBaudRate(QSerialPort::Baud1200);
break;
case 1:
mSerialPort.setBaudRate(QSerialPort::Baud2400);
break;
case 2:
mSerialPort.setBaudRate(QSerialPort::Baud4800);
break;
case 3:
mSerialPort.setBaudRate(QSerialPort::Baud9600);
break;
case 4:
mSerialPort.setBaudRate(QSerialPort::Baud19200);
break;
case 5:
mSerialPort.setBaudRate(QSerialPort::Baud38400);
break;
case 6:
mSerialPort.setBaudRate(QSerialPort::Baud57600);
break;
case 7:
mSerialPort.setBaudRate(QSerialPort::Baud115200);
break;
default:
mSerialPort.setBaudRate(QSerialPort::Baud1200);
break;
}
// 设置数据位
switch (data) {
case 0:
mSerialPort.setDataBits(QSerialPort::Data5);
break;
case 1:
mSerialPort.setDataBits(QSerialPort::Data6);
break;
case 2:
mSerialPort.setDataBits(QSerialPort::Data7);
break;
case 3:
mSerialPort.setDataBits(QSerialPort::Data8);
break;
default:
mSerialPort.setDataBits(QSerialPort::Data5);
break;
}
// 设置停止位
switch (stop) {
case 0:
mSerialPort.setStopBits(QSerialPort::OneStop);
break;
case 1:
mSerialPort.setStopBits(QSerialPort::OneAndHalfStop);
break;
case 2:
mSerialPort.setStopBits(QSerialPort::TwoStop);
break;
default:
mSerialPort.setStopBits(QSerialPort::OneStop);
break;
}
// 设置检查位
switch (check) {
case 0:
mSerialPort.setParity(QSerialPort::NoParity);
break;
case 1:
mSerialPort.setParity(QSerialPort::EvenParity);
break;
case 2:
mSerialPort.setParity(QSerialPort::OddParity);
break;
case 3:
mSerialPort.setParity(QSerialPort::SpaceParity);
break;
case 4:
mSerialPort.setParity(QSerialPort::MarkParity);
break;
default:
mSerialPort.setParity(QSerialPort::NoParity);
break;
}
}
- 由于项目要求以字节方式向串口发送数据,所以我们需要考虑使用到QByteArray类,将他实例化后并依次添加字节,最终将该字节对象传输至指定串口。
// 发送同步信号
QByteArray buffer;
buffer.append('\x90');
buffer.append('\xEB');
buffer.append('\x08');
buffer.append('\x00');
buffer.append('\xFF');
buffer.append('\x00');
buffer.append('\x00');
buffer.append('\x00');
buffer.append('\x00');
buffer.append('\x00');
buffer.append('\x07');
buffer.append('\x01');
if(true == mSerialPort.isOpen()){
mSerialPort.write(buffer);
}else
{
qDebug() << "fail";
}
成果展示