背景
QComboBox 是Qt中比较常用的一个输入控件,用于实现一个文本下拉列表。
在简单的应用场景中 QComboBox 完全可以满足要求,但是项目实践过程中会遇到以下问题:
①.需要实现比较复杂的下拉列表,比如同时显示图标、文字、按钮等, QComboBox 则不能满足使用;
②.需要能精确的定位到某一项(常用于删除)来动态的控制下拉列表,而 QComboBox 仅支持按 index 来删除下拉选项、但 index 是变化的。
设置代理
通常可以通过设置代理组件来解决上述在实践中的问题。
QComboBox内部是使用 Model/View 框架来维护下拉框内容的。因此可以定义一个 QListWidget,将这个 QListWidget 设置为 QComboBox 的 View,而将 QListWidget 的Model设置为 QComboBox 的 Model。QListWidget只是一个View类,因此我们还得自定义View类中的 Item。
代码示例
①.自定义 Item 类
class MyComboxItem : public QWidget
{
Q_OBJECT
public:
MyComboxItem(QWidget *parent = Q_NULLPTR );
~MyComboxItem();
private:
Ui::MyComboxItem ui;
private:
bool isMousePress = false;//鼠标按下
QLabel * textLabel = nullptr;//文本显示标签
QLabel * pictureLabel = nullptr;//图片显示标签
public:
void setItemText(const QString & m_str);
void setItemText(const QString & m_str,const QPixmap & m_pixmap);
protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
signals:
void selectText(const QString & m_str);
};
MyComboxItem::MyComboxItem(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
textLabel = new QLabel(this);
pictureLabel = new QLabel(this);
pictureLabel->setFixedWidth(30);
QHBoxLayout * mainLayout = new QHBoxLayout(this);
mainLayout->addWidget(pictureLabel);
mainLayout->addWidget(textLabel);
mainLayout->setContentsMargins(5, 5, 5, 5);
this->setLayout(mainLayout);
}
MyComboxItem::~MyComboxItem()
{
}
void MyComboxItem::setItemText(const QString & m_str)
{
textLabel->setText(m_str);
}
void MyComboxItem::setItemText(const QString & m_str, const QPixmap & m_pixmap)
{
textLabel->setText(m_str);
pictureLabel->setPixmap(m_pixmap);
}
void MyComboxItem::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
isMousePress = true;
}
}
void MyComboxItem::mouseReleaseEvent(QMouseEvent *event)
{
if (isMousePress)
{
emit selectText(textLabel->text());
isMousePress = false;
}
}
②.设置代理组件
widgetForCombox = new QListWidget(this);
ui.comboBox_mubiao->setModel(widgetForCombox->model());
ui.comboBox_mubiao->setView(widgetForCombox);
ui.comboBox_mubiao->setEditable(true);
③.添加条目
MyComboxItem * piciItem = new MyComboxItem(this);
piciItem->setItemText(pcID, QPixmap(":/image/Resources/feijiico.png"));
connect(piciItem, &MyComboxItem::selectText, [&](const QString & m_str) {
ui.comboBox_mubiao->setEditText(m_str);
ui.comboBox_mubiao->hidePopup();
});
QListWidgetItem * m_item = new QListWidgetItem(widgetForCombox);
widgetForCombox->setItemWidget(m_item, piciItem);
显示效果如下图: