上一篇内容Qt学习笔记1:创建一个QT的空项目介绍了初始Qt,不依赖Qt提供的模板框架,自己创建一个空的Qt项目。
本篇中,通过实际的小例子来熟悉一下Qt的使用 —— 串口工具。
可以参考:Qt学习笔记1:创建一个QT的空项目。这里不再详述。
本项目在设计时,以熟悉Qt使用为目的,串口工具的功能力求简洁实用。在后续的学习和开发中,可以逐步完善。
完成效果图如下所示,可以根据个人喜好做相应调整。
总体采用格点布局,将整个页面分为左右两部分:
左半边,又分为上(打开、关闭按钮)、中(参数配置)、下(其它扩展操作部件)。
右半边,又分为上(显示文本框)、中(发送数据输入文本框)、下(发送按钮)。
初始化设置布局代码:
QGridLayout *layout = new QGridLayout();
layout->addLayout(openAndCloseBtn(), 0, 0, 1, 1);
layout->addWidget(serialPortParamSettings(), 1, 0, 1, 1);
layout->addLayout(extraConfig(), 2, 0);
layout->addWidget(showTextEdit, 0, 1, 3, 6);
layout->addWidget(inputLineEdit, 7, 1, 1, 6);
layout->addWidget(sendBtn, 9, 6, 1, 1);
setLayout(layout);
Qt库提供了串口操作相关的类
QSerialPortInfo : 串口信息类
QSerialPort : 串口相关操作类
通过foreach语句,向系统查询串口信息:
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
qDebug() << "Name : " << info.portName();
qDebug() << "Description : " << info.description();
qDebug() << "Manufacturer: " << info.manufacturer();
// Example use QSerialPort
QSerialPort serial;
serial.setPort(info);
if (serial.open(QIODevice::ReadWrite))
{
qDebug() << "Name : add " << info.portName();
com->addItem(info.portName());
serial.close();
}
}
获取到系统资源后,尝试打开串口,若串口打开成功,将串口号添加到参数配置部件中,然后关闭串口。
通过此操作,可以查询到当前系统所有可用的串口号。
此操作在初始化时获取一次,为了方便动态调整串口信息,增加一个刷新串口号的按钮,手动获取。
串口参数包括串口号(自动获取)、波特率、数据位、校验位、停止位。
QGroupBox *groupBox = new QGroupBox();
QFormLayout *layout = new QFormLayout();
com = new QComboBox();
baudRate = new QComboBox();
dataBit = new QComboBox();
parity = new QComboBox();
stopBit = new QComboBox();
QStringList baudList;
QStringList parityList;
QStringList dataBitsList;
QStringList stopBitsList;
/* baud rate */
baudList<<"1200"<<"1800"<<"2400"<<"4800"<<"9600"
<<"14400"<<"19200"<<"38400"<<"56000"<<"57600"
<<"76800"<<"115200"<<"128000"<<"256000";
baudRate->addItems(baudList);
baudRate->setCurrentIndex(11);
/* parity */
parityList<<"无"<<"奇"<<"偶";
parity->addItems(parityList);
parity->setCurrentIndex(0);
/* data bits */
dataBitsList<<"5"<<"6"<<"7"<<"8";
dataBit->addItems(dataBitsList);
dataBit->setCurrentIndex(3);
/* stop bits */
stopBitsList<<"1"<<"1.5"<<"2";
stopBit->addItems(stopBitsList);
stopBit->setCurrentIndex(0);
/* vertical layout */
layout->setAlignment(Qt::AlignCenter);
layout->addRow(new QLabel(tr("串口号")), com);
layout->addRow(new QLabel(tr("波特率")), baudRate);
layout->addRow(new QLabel(tr("校验位")), parity);
layout->addRow(new QLabel(tr("数据位")), dataBit);
layout->addRow(new QLabel(tr("停止位")), stopBit);
/* group box */
groupBox->setTitle(tr("参数设置"));
groupBox->setLayout(layout);
此处使用groupBox部件,使用表单布局,将串口的参数加入到设置中去。效果如界面所示。
串口操作包括串口打开、关闭和串口参数设置。
在串口打开成功后,启动一个定时器,定时读取串口接收到的数据。
串口打开槽函数:
void Widget::openBtnClicked(void)
{
qDebug() << "Open serial port";
serial = new QSerialPort();
serial->setPortName(com->currentText());
if (serial->open(QIODevice::ReadWrite)) {
openBtn->setEnabled(false);
closeBtn->setEnabled(true);
sendBtn->setEnabled(true);
}
serial->setBaudRate(baudRate->currentText().toInt());
serial->setDataBits((QSerialPort::DataBits)dataBit->currentText().toInt());
serial->setStopBits((QSerialPort::StopBits)stopBit->currentIndex());
serial->setParity((QSerialPort::Parity)parity->currentIndex());
serial->setFlowControl(QSerialPort::NoFlowControl);
timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(upgradeRecvData()));
timer->start(200);
}
串口关闭槽函数:
void Widget::closeBtnClicked(void)
{
qDebug() << "Close serial port";
if (timer != NULL) {
qDebug() << "timer";
timer->stop();
}
if (serial != NULL) {
qDebug() << "serial";
serial->close();
delete serial;
serial = NULL;
}
openBtn->setEnabled(true);
closeBtn->setEnabled(false);
sendBtn->setEnabled(false);
}
定时器时间到,读取串口接收懂啊的数据,显示在文本框中。
此处简易的串口工具,没有设置显示的最大缓冲区、保存日志等操作,可自行完善。
在串口发送数据后,自动增加一个换行,方便命令输入的使用。
数据接收和显示的槽函数:
void Widget::upgradeRecvData(void)
{
recvData = serial->readAll();
if (recvData != NULL) {
showTextEdit->append(recvData);
}
recvData.clear();
}
数据发送的槽函数:
void Widget::sendBtnClicked(void)
{
QByteArray buf = inputLineEdit->text().toLocal8Bit();
serial->write(buf);
serial->write("\n");
inputLineEdit->clear();
}
源码下载链接:Qt串口工具