到我的空间查看完整文档:
http://hi.baidu.com/yafeilinux/blog/item/54f4f845f9ed7646510ffe8c.html
本文一开始先讲解对程序的改进,在文章最后将要讲解一些重要问题。
第一,在窗口中加入一些组合框Combo Box,它们的名称及条目如下:
串口:portNameComboBox,条目为:COM1,COM2
波特率:baudRateComboBox,条目为:9600,115200
数据位:dataBitsComboBox,条目为:8,7
校验位:parityComboBox,条目为:无,奇,偶
停止位:stopBitsComboBox,条目为:1,2
(注:在窗口上的Combo Box上双击,在弹出的对话框上按“+”号,可添加条目。)
改好的窗口如下所示:
第二,更改“打开串口”按钮的单击事件槽函数。
void MainWindow::on_openMyComBtn_clicked()
{
QString portName = ui->portNameComboBox->currentText(); //获取串口名
myCom = new Win_QextSerialPort(portName,QextSerialBase::EventDriven);
//定义串口对象,并传递参数,在构造函数里对其进行初始化
myCom ->open(QIODevice::ReadWrite); //打开串口
if(ui->baudRateComboBox->currentText()==tr("9600")) //根据组合框内容对串口进行设置
myCom->setBaudRate(BAUD9600);
else if(ui->baudRateComboBox->currentText()==tr("115200"))
myCom->setBaudRate(BAUD115200);
if(ui->dataBitsComboBox->currentText()==tr("8"))
myCom->setDataBits(DATA_8);
else if(ui->dataBitsComboBox->currentText()==tr("7"))
myCom->setDataBits(DATA_7);
if(ui->parityComboBox->currentText()==tr("无"))
myCom->setParity(PAR_NONE);
else if(ui->parityComboBox->currentText()==tr("奇"))
myCom->setParity(PAR_ODD);
else if(ui->parityComboBox->currentText()==tr("偶"))
myCom->setParity(PAR_EVEN);
if(ui->stopBitsComboBox->currentText()==tr("1"))
myCom->setStopBits(STOP_1);
else if(ui->stopBitsComboBox->currentText()==tr("2"))
myCom->setStopBits(STOP_2);
myCom->setFlowControl(FLOW_OFF);
myCom->setTimeout(500);
connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));
//信号和槽函数关联,当串口缓冲区有数据时,进行读串口操作
ui->openMyComBtn->setEnabled(false); //打开串口后“打开串口”按钮不可用
ui->closeMyComBtn->setEnabled(true); //打开串口后“关闭串口”按钮可用
ui->sendMsgBtn->setEnabled(true); //打开串口后“发送数据”按钮可用
ui->baudRateComboBox->setEnabled(false); //设置各个组合框不可用
ui->dataBitsComboBox->setEnabled(false);
ui->parityComboBox->setEnabled(false);
ui->stopBitsComboBox->setEnabled(false);
ui->portNameComboBox->setEnabled(false);
}
这里我们先获取串口的名称,然后调用另一个构造函数对myCom进行定义,这个构造函数里没有串口的设置参数。然后打开串口。然后获取串口的设置数据,用setBaudRate();等一系列函数进行串口的设置,这些函数都在win_qextserialport.cpp文件中定义,如下图。
对于这几个函数应该很好理解,这里不再解释。在最后我们对添加的那几个组合框进行了不可用设置,使其在串口打开的情况下不能选择。
程序如下:
第三,更改“关闭串口”按钮单击事件的槽函数。
void MainWindow::on_closeMyComBtn_clicked()
{
myCom->close();
ui->openMyComBtn->setEnabled(true); //关闭串口后“打开串口”按钮可用
ui->closeMyComBtn->setEnabled(false); //关闭串口后“关闭串口”按钮不可用
ui->sendMsgBtn->setEnabled(false); //关闭串口后“发送数据”按钮不可用
ui->baudRateComboBox->setEnabled(true); //设置各个组合框可用
ui->dataBitsComboBox->setEnabled(true);
ui->parityComboBox->setEnabled(true);
ui->stopBitsComboBox->setEnabled(true);
ui->portNameComboBox->setEnabled(true);
}
这里只是加入了一些使组合框在“关闭串口”按钮按下后变为可用的语句。
第四,更改main.cpp文件。
#include <QtGui/QApplication>
#include <QTextCodec> //加入头文件
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
//使程序可处理中文
MainWindow w;
w.show();
return a.exec();
}
因为上面的语句中用到了中文,为了能使程序识别中文,我们需要在主函数中加入这些语句。
第五,运行程序。
到这里,整个程序就完全写完了。
重要问题说明:
(下面所说的第一个程序是指第一篇文章中写的那个程序,第二个程序是指第三篇文章中那个程序,第三个程序是指本篇文章中所写的程序。)
问题一:第一个程序中
struct PortSettings myComSetting = {BAUD9600,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,500};
myCom = new Win_QextSerialPort("com1",myComSetting,QextSerialBase::EventDriven);
这两句代码如果换为下面一行:
myCom = new Win_QextSerialPort("com1",QextSerialBase::EventDriven);
你再运行一下程序,是不是还能用?那我们的串口设置的结构体myComSetting没有用吗?你可以把上面的结构体里的波特率由9600改为115200,如果这个结构体有用,那么程序不可能再接收到数据,不过,你再运行一下程序,是这样吗?
如此看来,我们对串口进行的设置果真没用,那默认的串口设置是什么呢?我们先看下一个问题。
问题二:我们同时打开第三个程序和第二个程序。(注意:两个程序的串口不能同时打开,所以打开一
个程序的串口时要将另一个程序的串口关闭。)
我们先在第三个程序上按默认设置打开串口,发送数据1。然后关闭串口,在第二个程序上打开串口,发送数据1。可以看到两个程序上接受到的信息都正确。如下图。
我们关闭第二个程序上的串口,再将第三个程序上设置为奇校验,然后打开串口,发送数据1,可以看到其收到的数据显示乱码。这时我们关闭第三个程序上的串口,打开第二个程序上的串口,发送数据1,你会惊奇地发现,它收到的信息也是乱码。如下图。
这到底是怎么回事呢?我们也可以去网上下载其他的串口助手进行实验,也可以改变波特率进行实验。由所有的结果得出的结论只能是:我们用那个结构体作为参数传过去后,并没有对串口进行设置,而程序运行使用的串口设置是系统以前保留的设置。那么,为什么会这样呢?我们看下面的一个问题。
问题三:我们将第三个程序中的那行代码
myCom ->open(QIODevice::ReadWrite);
放到设置串口的语句之后,
connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));
这句之前,然后再运行程序。你会发现程序的串口设置功能已经不起作用了。
其实,上面的三个问题是一个问题,它的结论就是,写串口程序时,要先打开串口再对它进行设置,不然设置就不会起作用。所以,这里应该说明,第一个和第二个程序都是不太正确的,正确的方法应该是像第三个程序一样,先定义Win_QextSerialPort类对象,然后打开串口,再用那几个函数对串口进行设置。
到这里整篇文章就结束了。对于其中的一些问题也只是我个人的观点,由于水平有限,所以理解上可能会有偏差,或者错误,请广大网友批评指正。我写这篇文章的目的只是想让Qt初学者能更轻松的用Qt写出串口通信程序,及掌握Qt写程序时的一些技巧。如果你从我的文章中学到了一点知识,那么我的这篇文章就算是没有白写。
最后,如果你喜欢我的写作风格,并且初学Qt,可以在我的空间查看Qt Creator系列教程,希望能对你的入门有所帮助。
文章评论(0条评论)
登录后参与讨论