项目需要设计一个带下拉选择的ComboBox,这里重写一个QComboBox实现一下
查了一下文档发现,选择QComboBox作为模板,设计ComboBox下拉界面的model和view,用checkBox作为item,实现一下点击功能,即可实现。
这里解决了点击CheckBox空白处无法进行选择,滚动条显示的异常,二次打开下拉菜单item项缺失的问题,可以参考一下
1.头文件
#include
#include
#include
#include
#include
#include
#include
#include
#include
class CheckComboBox: public QComboBox
{
Q_OBJECT
public:
explicit CheckComboBox(QWidget *parent = 0);
~CheckComboBox();
/*重置*/
void resetListWidget();
/*赋值*/
void setDataList(const QList<QString> &dataList, const QString &recordText = "");
/*获取combox含有的所有名称*/
QList<QString> getLstName();
/*获取combox选中的所有名称*/
QList<QString> getSelectLstName();
private slots:
void updateCheckData(const int &index);
void updateShowText();
protected:
virtual void showPopup();
virtual void hidePopup();
private:
QLineEdit *m_textShow;
QListWidget *m_widgetList;
QList<QCheckBox *> m_checkBoxList;
QList<QString> m_lstName;
};
2.功能和实现
#include "checkcombobox.h"
CheckComboBox::CheckComboBox(QWidget *parent)
: QComboBox(parent)
, m_textShow(new QLineEdit(this))
, m_widgetList(new QListWidget(this))
{
m_textShow->setText(" ");
m_textShow->setReadOnly(true);
m_textShow->setStyleSheet("background:#444444;");
setLineEdit(m_textShow);
setMinimumWidth(120);
setDataList(QList<QString>(),QString());
// 获取点击状态
connect(this, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
[=](int index)
{
updateCheckData(index);
});
}
CheckComboBox::~CheckComboBox()
{
}
void CheckComboBox::resetListWidget()
{
if(m_widgetList != NULL)
{
delete m_widgetList;
m_widgetList = new QListWidget(this);
}
m_checkBoxList.clear();
}
void CheckComboBox::setDataList(const QList<QString> &data, const QString &recordText)
{
m_lstName = data;
//清空listwidget
resetListWidget();
QStringList itemNameList = recordText.split(";");
for (int i = 0; i < data.size(); i++)
{
QListWidgetItem *item = new QListWidgetItem(m_widgetList);
item->setData(Qt::UserRole, i);
m_widgetList->addItem(item);
QCheckBox *checkBox = new QCheckBox(this);
checkBox->setText(data.at(i));
m_checkBoxList.append(checkBox);
m_widgetList->setItemWidget(item, checkBox);
if (itemNameList.contains(data.at(i)))
{
checkBox->setChecked(true);
}
connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(updateShowText()));
}
setModel(m_widgetList->model());
setView(m_widgetList);
m_textShow->setText(recordText);
}
QList<QString> CheckComboBox::getLstName()
{
return m_lstName;
}
QList<QString> CheckComboBox::getSelectLstName()
{
QList<QString> sellstName;
for (int i = 0; i < m_checkBoxList.count(); i++)
{
if (m_checkBoxList[i]->isChecked())
{
sellstName.append(m_checkBoxList[i]->text());
}
}
return sellstName;
}
void CheckComboBox::updateCheckData(const int &index)
{
if (index < 0)
{
return;
}
if (this->count() > 0)
{
setCurrentIndex(0);
}
// 取反
if (m_checkBoxList.count() > index)
{
if (m_checkBoxList[index]->isChecked())
{
m_checkBoxList[index]->setChecked(false);
}
else
{
m_checkBoxList[index]->setChecked(true);
}
}
}
void CheckComboBox::updateShowText()
{
QList<QString> showTextList = getSelectLstName();
QString showText;
for (int i = 0; i < showTextList.count(); i++)
{
showText += showTextList[i];
if (i + 1 != showTextList.count())
{
showText += ";";
}
}
m_textShow->setText(showText);
}
void CheckComboBox::showPopup()
{
QComboBox::showPopup();
}
void CheckComboBox::hidePopup()
{
// 重置一下滚动条,防止出现widgetList的滚动条在界面最底下
QScrollBar *bar = m_widgetList->verticalScrollBar();
bar->setValue(bar->minimum());
QComboBox::hidePopup();
}