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