之前的博客里介绍了Qt中串口设备的基本操作,这些功能虽然能够实现简单的串口收发功能,但都是在后台运行的,使用Qt自然不能埋没了它能方便的制作UI的特点,那么接下来我们就来对串口助手的UI界面进行一下简单的设计。
话不多说,先看图》》》
有点丑,而且功能也有些复杂,这次我们先不讲那么多,先说说和串口配置相关的这一部分。
这一部分很简单,实际上就是几个label作为标题,combo Box作为选择输入框。在Qt的Ui编辑界面拖拽拉入即可。
在添加每个控件的时候,给每个控件赋予有意义的名字是非常好的习惯。
控件排布好之后,我们拉出一个按钮,命名为Buttom_Open,设置按钮上的文字为“打开串口”。右击转到槽,建立一个槽函数用做控制串口的打开和关闭。
设置动作 当点击clicked的时候 执行打开串口,再次点击的时候关闭串口。
bool MainWindow::on_Button_Open_clicked()
{
if(ui->Button_Open->text()==tr("打开串口"))
{
ui->Button_Open->setText(tr("关闭串口"));
}
else
{
//关闭串口
ui->Button_Open->setText(tr("打开串口"));
ui->Send_Button->setEnabled(false);
}
return true;
}
下面是这次要说的重点了:combo Box
先说说在UI编辑界面对combo Box有哪些设置
双击波特率对应的下拉控件 我们可以看到这个界面
在这个界面中我们可以在编辑框中填入预设好的下拉选项,常用波特率的设置就可以用这种方法。
不过,难免有些时候遇到了不常用的波特率,所以我还在右侧的选项卡中打开了编辑使能开关,也就是可以自由写入想要的波特率。
其他的下拉列表也可以以此类推进行配置。我在这里就不再赘述。
说到此处,我突然想提一句,就是在我们研究Qt的时候,一个很好的自学方法就是按F1召唤出帮助菜单,根据说明进行尝试,总有意想不到的收获。
这次我们需要用代码实现的控件功能有
currentText(); setEnabled(false); setCurrentText(value);
然后如上一次所说,我们打开串口需要设置几个串口的参数,那么我们使用combo Box之后怎么将它的值作为参数传递进去呢?不要担心,你想要的几乎都被封装好了,你只需要输入ui按键盘上的 ‘.’按键 就会自动跳出备选项,然后你可以选择对应的下拉输入控件,在按‘.’选择我们这次需要的currentText();就可以了。是不是很方便呢。
最后的结果就是在代码界面上显示了这样的内容
serial->setPortName(ui->cBox_Port->currentText());//将cBox_Port当前显示的内容作为文本参数返回。
我们把这些内容组合一下放到按钮的打开串口的if里面,就大功告成了。
我们还可以用
ui->cBox_BaudRate->setCurrentText(value);
来对初始值进行预设,虽然我们可以在界面上直接选择当前的内容作为预设,但是如果我们想在不动界面的情况下进行修改就必须要用到代码来实现了,这次我们先不讲。
当我们打开了串口设备之后,我们不希望这些选项框的内容再发生变化了,我们就可以用setEnabled(false);来关闭使能,让操作者无法修改这些内容,而关闭串口的时候在打开使能,允许重新编辑,这些都是程序的老套路啦,防止有人进行错误操作的。
话说到这,我突然想起前一阵子看到一个不懂软件的大叔操作office的一个设置,软件明明已经关闭了使能(因为条件不满足,不可编辑)变成了灰色的框框,他还再哪里点了十多分钟,边按还一直叨咕着为什么修改不了。。。。(PS:他当时还不让我插话,可能是想显示他很厉害,无语x1000。。。)题外话说多了,嗯 最后我还是好心的帮他解决了 哈哈哈~
如果没有进行禁止使能的设置,软件就可能出现一些你意想不到的状况,谁知道你的用户会进行什么奇葩的操作呢,所以作为软件设计者还是应该防微杜渐的。
下面是我这个上位机中打开串口部分的代码,写的比较乱,其中还涉及到了我的黑名单策略,这是和串口设备扫描结合使用了,我会在后面的内容中进行说明。
bool MainWindow::on_Button_Open_clicked()
{
if(ui->Button_Open->text()==tr("打开串口"))
{
serial = new QSerialPort;
//设置串口名
serial->setPortName(ui->cBox_Port->currentText());
//打开串口
if(serial->open(QIODevice::ReadWrite)==false)
{
if(QSerialPortInfo(*serial).isNull()==false)//如果存在此设备且打不开,则加入黑名单,否则不加入黑名单
{
if(Black_serial_list.indexOf(ui->cBox_Port->currentText())==-1)//当打不开的串口不存在黑名单里时,再写入黑名单 防止重复写入
Black_serial_list.append(ui->cBox_Port->currentText()); //将错误串口号加入临时黑名单
QMessageBox::warning(NULL,"warning",tr("is NULL!"));
}
QMessageBox::warning(NULL,"warning",tr("OPEN UART Fail!"));
ui->cBox_Port->setCurrentIndex(0);
return false;
}
//设置波特率
serial->setBaudRate(ui->cBox_BaudRate->currentText().toInt());
//设置数据位数
switch(ui->cBox_BitNum->currentIndex()) //index是指的第几个
{
case 0: serial->setDataBits(QSerialPort::Data8); qDebug() << tr("8");break;
case 1: serial->setDataBits(QSerialPort::Data7); qDebug() << tr("7");break;
case 2: serial->setDataBits(QSerialPort::Data6); qDebug() << tr("6");break;
case 3: serial->setDataBits(QSerialPort::Data5); qDebug() << tr("5");break;
default: break;
}
//设置奇偶校验
if(ui->cBox_Parity->currentText().indexOf("None",0)==0)
{
serial->setParity(QSerialPort::NoParity);
qDebug() << tr("None");
}
else if(ui->cBox_Parity->currentText().indexOf("Even",0)==0)
{
serial->setParity(QSerialPort::EvenParity);
qDebug() << tr("Even");
}
else if(ui->cBox_Parity->currentText().indexOf("Odd",0)==0)
{
serial->setParity(QSerialPort::OddParity);
qDebug() << tr("Odd");
}
else if(ui->cBox_Parity->currentText().indexOf("Space",0)==0)
{
serial->setParity(QSerialPort::SpaceParity);
qDebug() << tr("Space");
}
else if(ui->cBox_Parity->currentText().indexOf("Mark",0)==0)
{
serial->setParity(QSerialPort::MarkParity);
qDebug() << tr("Mark");
}
else if(ui->cBox_Parity->currentText().indexOf("Unknown",0)==0)
{
serial->setParity(QSerialPort::UnknownParity);
qDebug() << tr("Unknown");
}
//设置停止位
switch(ui->cBox_Stop->currentIndex())
{
case 0: serial->setStopBits(QSerialPort::OneStop); qDebug() << tr("1");break;
case 1: serial->setStopBits(QSerialPort::OneAndHalfStop); qDebug() << tr("1.5");break;
case 2: serial->setStopBits(QSerialPort::TwoStop); qDebug() << tr("2");break;
default: break;
}
//设置流控制
serial->setFlowControl(QSerialPort::NoFlowControl);
//关闭设置菜单使能
ui->cBox_Port->setEnabled(false);
ui->cBox_BaudRate->setEnabled(false);
ui->cBox_BitNum->setEnabled(false);
ui->cBox_Parity->setEnabled(false);
ui->cBox_Stop->setEnabled(false);
//发送使能
ui->Send_Button->setEnabled(true);
//显示标签页
//ui->tabWidget->show();
//连接串口读取函数
QObject::connect(serial, &QSerialPort::readyRead, this, &MainWindow::Read_Data);
ui->Button_Open->setText(tr("关闭串口"));
}
else
{
//关闭串口
serial->clear();
serial->close();
serial->deleteLater();
//恢复设置使能
ui->cBox_Port->setEnabled(true);
ui->cBox_BaudRate->setEnabled(true);
ui->cBox_BitNum->setEnabled(true);
ui->cBox_Parity->setEnabled(true);
ui->cBox_Stop->setEnabled(true);
ui->Button_Open->setText(tr("打开串口"));
ui->Send_Button->setEnabled(false);
}
return true;
}
代码粗糙,欢迎斧正~