第一代光电小工具(二)
[toc]
关键字: Qt
、Qml
、QCustomPlot
、串口
、QSerialPort
项目介绍
欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。
在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。
在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资源消耗,以确保我们的项目在各种平台和设备上都能够高效运行。
无论您是对 QML 和 C++ 开发感兴趣,还是需要我们为您构建复杂的用户界面和后端逻辑,我们都随时准备为您提供支持。请随时联系我们,让我们一同打造现代化、高性能的 QML & C++ 项目!
重要说明☝
☀该专栏更新到第三代软件开发时将转为收费专栏
串口
接着上篇,我们接着聊聊我这个小工具中还用到了什么Qt的内容。
当你不需要追求极致的效率时,Qt自带的串口类QSerialPort是一个方便且易于使用的工具,可以满足大多数串口通信需求。以下是关于QSerialPort的一些丰富信息:
- 打开和配置串口:使用QSerialPort类可以轻松打开和配置串口连接。通过设置波特率、数据位、停止位、奇偶校验等参数,可以适应不同的串口设备。
- 读取和写入数据:QSerialPort提供了读取和写入数据的函数。你可以使用
read()
函数读取串口接收缓冲区中的数据,使用write()
函数向串口发送数据。此外,还有一些其他函数用于读取特定数量的字节、等待特定事件等。- 事件驱动的串口通信:QSerialPort使用Qt的事件驱动机制,可以监听串口接收缓冲区中的数据到达、串口错误发生等事件。你可以通过继承QSerialPort并重写虚拟函数
void QIODevice::readyRead()
来处理接收到的数据。- 支持流控制:QSerialPort支持硬件流控制(RTS/CTS、DTR/DSR)和软件流控制(XON/XOFF)。你可以通过设置相应的属性实现流控制功能。
- 跨平台支持:QSerialPort是跨平台的,它支持在多个操作系统上使用,如Windows、Linux和macOS等。这使得你可以轻松地开发可移植的串口通信应用程序。
- 错误处理:QSerialPort提供了一些函数和信号来处理串口通信中的错误情况。你可以使用
error()
函数获取最后发生的错误代码,使用errorString()
函数获取错误的人类可读描述。- 示例和文档:Qt官方提供了丰富的示例代码和文档,帮助你理解和使用QSerialPort类。你可以查阅Qt的官方文档,其中包含详细的函数说明和示例代码。
总之,Qt自带的串口类QSerialPort
提供了一个便捷的接口来进行串口通信。无论是简单的串口数据收发还是更复杂的串口协议交互,QSerialPort
都能满足大部分需求,并提供跨平台的支持。
初始化串口及遍历可用串口代码如下:
/**
* @brief MainWindow::initSerialPort
* 初始化串口
*/
void MainWindow::initSerialPort()
{
if(!m_serialPort) //判断串口是否被初始化
{
m_serialPort = new QSerialPort(); //初始化串口
QObject::connect(m_serialPort,&QSerialPort::readyRead,this,&MainWindow::readSerialData);
}
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) //枚举当前可用串口
{
//自动查找可用的串口
QSerialPort serial;
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))
{
ui->comboBox_serialPory->addItem(serial.portName());
serial.close();
}
}
}
打开串口及基本设置代码如下
/**
* @brief MainWindow::openSerialPort
* @return
* 初始化串口
*/
bool MainWindow::openSerialPort()
{
if(m_serialPort)
{
m_serialPort->setPortName(ui->comboBox_serialPory->currentText()); //设置串口名称
if(m_serialPort->open(QIODevice::ReadWrite)) //打开串口模式为读写模式
{
m_serialPort->setBaudRate(QSerialPort::Baud115200); //设置串口波特率为115200
m_serialPort->setDataBits(QSerialPort::Data8); //设置串口数据位为8位
m_serialPort->setParity(QSerialPort::NoParity); //设置串口没有校验位
m_serialPort->setStopBits(QSerialPort::OneStop); //设置串口停止位为1位
m_serialPort->setFlowControl(QSerialPort::NoFlowControl); //设置串口流控为无
return true;
}
else
{
QMessageBox::warning(this,"警告","打开串口失败,请重试",QMessageBox::Ok); //弹窗警告
return false;
}
}
else
{
return false;
}
}
如果最求极致,那就手写串口驱动,跳过系统内核,把部分物业逻辑封装到驱动中,这样可能会有更高的效率,不过目前我在这小工具中怎么使用就可以了。
QCustomPlot 部分
上一篇中已经分享了目前QCustomPlot
包含的内容,单纯对QCustomPlot
感兴趣的,可以直接去哪里看博主遇到的坑,
这部分在第一代中其实没有啥实用的分享,也是第一次使用,很多都是不是理想,只是用在小工具上,在当时的环境下,恰好满足罢了,后面经过在正式项目对QCustomPlot
有了稍微那么一丢丢的研究,会分享更多,同时也会包含到QCustomPlot
的专栏里面。这里可以分享几段代码
开启OpenGl
通过看博主控件的命名应该也会发现了吧,我开始真实是打算用QChart 的,不过是在没有解决数据卡顿问题。这里开启OpenGL 直接调用QCustomPlot现成的接口就可以,不过要注意这个不是一定好使,等后面就发会发了。
ui->widget_chart->setOpenGl(true);
ui->widget_chart_2->setOpenGl(true);
ui->widget_chartShow->setOpenGl(true);
ui->widget_chartShow_2->setOpenGl(true);
更新曲线
这个很重要,而且最好建议这么做,就是找一个定时器专门用来重新绘制曲线,代码如下
/**
* @brief MainWindow::slot_upDateQCustomplotPainter
* 定时刷新QCustomPlot界面
*/
void MainWindow::slot_upDateQCustomplotPainter()
{
if(ui->tabWidget_mainFrame->currentIndex() == 0)
{
ui->widget_chart->xAxis->setRange(m_dataIndex,840,Qt::AlignRight); // 更新x轴范围
ui->widget_chart_2->xAxis->setRange(m_dataIndex,840,Qt::AlignRight); // 更新x轴范围
ui->widget_chart->yAxis->rescale(true); // 设置Y轴状自适应
ui->widget_chart_2->yAxis->rescale(true); // 设置Y轴状自适应
ui->widget_chart->replot(QCustomPlot::rpQueuedReplot); // 刷新界面显示
ui->widget_chart_2->replot(QCustomPlot::rpQueuedReplot); // 刷新界面显示
}
if(ui->tabWidget_mainFrame->currentIndex() == 1)
{
ui->widget_chartShow->yAxis->rescale(true); // 设置Y轴状自适应
ui->widget_chartShow_2->yAxis->rescale(true); // 设置Y轴状自适应
ui->widget_chartShow->replot(QCustomPlot::rpQueuedReplot); // 刷新界面显示
ui->widget_chartShow_2->replot(QCustomPlot::rpQueuedReplot); // 刷新界面显示
}
}
好了,小工具涉及到的内容就分享到这里。
总结一下
最终大家看到的小工具是一个可以满足当时使用的小软件,但是这个已经不是这个小工具最开始的样子了,最开的小工具只有连接串口,显示数据,而且还是用的QChart
,在发现使用QChart
无法解决卡顿问题后,换了QCustomPlot
模块,后期为了方便标记数据,有做了数据类型标记,就是通过不同颜色的曲线来确定数据类型。
在最开始进需要展示一条曲线,后期发现一条曲线解决不了问题,所以吧后台的参考数据也一并取出。用作后期数据分析。
所以,做项目不是一次性的,需要我们不断的调整,以适应当下的使用需求,也不是一层不便的,各位小伙伴不比为了频繁的需求变化为烦恼,同时通过不断的改进自己的代码质量,也是对自己的一种提升和总结。