需求:
-
下拉列表有复选功能
-
不可编辑
-
显示所有选中项
关于QComboBox的复选功能有几种方案:
-
QStandardItemModel + QStandardItem
-
QListWidget + QListWidgetItem
-
Model/View + QItemDelegate
当然,还有其它更好的方式,这里就不再过多介绍了,下面介绍一种比较简单的:
QListWidget + QListWidgetItem + QCheckBox
//试验流程设备添加 QComboBox *box2 = new QComboBox; QListWidget *pListWidget = new QListWidget; QLineEdit *pLineEdit = new QLineEdit; //添加仿真设备 for (int i = 0; i<m_vec_simdevicename.size(); i++) { QListWidgetItem *pItem = new QListWidgetItem(pListWidget); pListWidget->addItem(pItem); pItem->setData(Qt::UserRole, i); QCheckBox *pCheckBox = new QCheckBox(this); pCheckBox->setText(m_vec_simdevicename[i]); pListWidget->addItem(pItem); pListWidget->setItemWidget(pItem, pCheckBox); connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged(int))); } box2->setModel(pListWidget->model()); box2->setView(pListWidget); box2->setLineEdit(pLineEdit); box2->setMinimumWidth(100); pLineEdit->setReadOnly(true); connect(pLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &))); m_vec_listWidget.push_back(pListWidget); m_vec_lineedit.push_back(pLineEdit); m_vec_process_devicecombox.push_back(box2);
void CTestCfgWidget::stateChanged(int state) { bSelected = true; QString strSelectedData(""); strSelectedText.clear(); QObject *object = QObject::sender(); QCheckBox *pSenderCheckBox = static_cast<QCheckBox*>(object); //需要确定是哪一个下拉框中的checkbox发出的状态改变信号 //如何确定? //遍历所有的下拉框中的复选框,找到信号发送方,,确定是哪一个下拉框 int index = 0; for (index=0;index<m_vec_listWidget.size();index++) { QListWidget *pListWidget = m_vec_listWidget[index]; int nCount = pListWidget->count(); for (int k=0;k<nCount;k++) { QListWidgetItem *pItem = pListWidget->item(k); QWidget *pWidget = pListWidget->itemWidget(pItem); QCheckBox *pCheckBox = (QCheckBox *)pWidget; //找到信号发送方,确定是哪一个下拉框 if (pSenderCheckBox == pCheckBox) { goto find; } } } find: qDebug() << "find is true" << endl; QListWidget *pListWidget = m_vec_listWidget[index]; QLineEdit *pLineEdit = m_vec_lineedit[index]; int nCount = pListWidget->count(); for (int i = 0; i < nCount; ++i) { QListWidgetItem *pItem = pListWidget->item(i); QWidget *pWidget = pListWidget->itemWidget(pItem); QCheckBox *pCheckBox = (QCheckBox *)pWidget; if (pCheckBox->isChecked()) { QString strText = pCheckBox->text(); strSelectedData.append(strText).append(";"); } //所点击的复选框 if (pSenderCheckBox == pCheckBox) { int nData = pItem->data(Qt::UserRole).toInt(); qDebug() << QString("I am sender...id : %1").arg(nData); } } if (strSelectedData.endsWith(";")) strSelectedData.remove(strSelectedData.count() - 1, 1); if (!strSelectedData.isEmpty()) { //ui.comboBox->setEditText(strSelectedData); strSelectedText = strSelectedData; pLineEdit->setText(strSelectedData); pLineEdit->setToolTip(strSelectedData); } else { pLineEdit->clear(); //ui.comboBox->setEditText(""); } bSelected = false; } void CTestCfgWidget::textChanged(const QString &text) { QObject *object = QObject::sender(); QLineEdit *psenderlineedit = static_cast<QLineEdit*>(object); int index = 0; for (int index=0;index<m_vec_lineedit.size();index++) { if (psenderlineedit == m_vec_lineedit[index]) { break; } } QLineEdit *pLineEdit = m_vec_lineedit[index]; if (!bSelected) pLineEdit->setText(strSelectedText); }
当点击的复选框状态改变时候,会发送stateChanged信号,槽中通过sender来获取信号的发送者,然后可以获取所需要的数据(比如:可以通过setData保存一些自定义的数据),遍历所有的复选框,获取选中项的数据进行显示。
中间遇到一个小问题,当点击空白处,下来列表会进行收回,此时QLineEdit的数据将会被自动清空,所以此处判断QLineEdit的textChanged来进行恢复。
效果: