环境:win10,Qt5.9.7 + msvc2017
问题:做项目的时候用到QComboBox展示串口号,但是有个问题是因为初始化的时候获取串口号列表,软件运行起来后,串口更新了也无法识别,必须重启软件重新初始化才行。(因为一些原因无法做成弹框等形式)
查询资料发现QComboBox是没有类似clicked的信号,所以没法直接用内置的信号槽处理。
后来在一篇pyqt5中的博客(https://blog.csdn.net/pzx_hkq/article/details/78794829)中看到类似的重写showPopup()函数的方法,按照一样的思路实现了。
先上代码:
头文件部分
#ifndef CUSTOMCOMBOBOX_H
#define CUSTOMCOMBOBOX_H
#include <QComboBox>
#include <QtSerialPort/QSerialPortInfo>
#include <QtSerialPort/QSerialPort>
class CustomComboBox : public QComboBox
{
Q_OBJECT
public:
explicit CustomComboBox(QWidget *parent = nullptr,bool askoccupy=0);
~CustomComboBox()override;
void showPopup()override;
void setAskOccupy(const bool &flag);
private:
bool mAskOccupy;
};
#endif // CUSTOMCOMBOBOX_H
.cpp部分
#include "customcombobox.h"
/**
* @projectName CustomComboBox
* @author darkcell-yao
* @datetime 2019-12-27 周五 15:38:03:264
* @brief 用于串口号遍历查询
* @other 使用时如果参数askoccupy为true则确认是否该串口被占用,被占用则不添加
* 如果参数askoccupy为false则添加所有存在串口,此标志默认false,可以用
* setAskOccupy修改
*/
CustomComboBox::CustomComboBox(QWidget *parent,bool askoccupy) :
QComboBox(parent),mAskOccupy(askoccupy)
{
}
CustomComboBox::~CustomComboBox()
{
}
void CustomComboBox::showPopup()
{
QString current_text = this->currentText();
QStringList namelist;
namelist.clear();
QComboBox::clear();
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
QSerialPort serial;
serial.setPort(info);
if(mAskOccupy){
if(serial.open(QIODevice::ReadWrite)) //遍历可打开串口
{
namelist.append(serial.portName());
serial.close();
}
else{
if(serial.portName()==current_text){ //当前串口如果打开也要添加
namelist.append(serial.portName());
}
}
}
else{ //遍历添加所有串口
namelist.append(serial.portName());
}
}
QComboBox::addItems(namelist);
setCurrentText(current_text);
QComboBox::showPopup();
}
void CustomComboBox::setAskOccupy(const bool &flag)
{
mAskOccupy = flag;
}
其中showPopup()函数中foreach内容是查询可用串口号,可以用其他的实现方法或其他的操作代替。
最后两句一定要加,第一句不加会出现列表内容未添加到控件中的情况,第二句不加会出现下拉框拉不下来的现象。
QComboBox::addItems(namelist);//添加到QComboBox中
QComboBox::showPopup();//下拉展示
另外,最开始的控件清空也是需要的,否则会出现不断累积的现象。
使用的话,可以直接将这两个文件添加到项目,然后再*.pro文件添加serialport模块,可以自己用代码实现添加,也可以在ui界面拖拽QWidget窗口,右键提升为,然后按照下图设置,则将这个QWidget提升为CustomComboBox。