QT使用QListWidget+QChececkBox实现多选功能

功能需求描述:要求制作一个自定义控件CheckBoxList,控件中有N个复选框QCheckBox,当任何一个复选框反转时,该控件发出信号,信号指示出:此时哪几个复选框处于选中状态。

解决方案:显示出一列复选框,用QListWidget来干最合适了,默认情况下QListWidget添加的条目item是纯文字,而这里我们要求添加的条目是复选框。

同理,也可以使用树形控件QTreeWidget、表格控件QTableWidget来组织自定义控件。本文仅以列表形组织为例了:

 

UI设计界面、把它应用在别的程序中的运行效果,分别如下所示:
                
           

为了使这个自定义控件更加好用,还添加了全选、全不选、正则筛选等功能,这些功能都没什么难度。最关键的部分是要搞懂如何在QListWidget里面添加QCheckBox。

其实也简单,在ui中拖出一个或者用代码new一个QListWidget,然后在窗口的构造函数中对QListWidget添加条目即可:
 

for(int i = 0; i < cnt; i++)
    {
        QListWidgetItem *item = new QListWidgetItem();
        QCheckBox *checkBox= new QCheckBox ();

        ui->listWidget->addItem(item);//在ListWidget中添加一个条目
        ui->listWidget->setItemWidget(item, checkBox);//在这个条目中放置CheckBox
        icheckBox->setText(QString("checkBox_%1").arg(i));
        
        //把所有checkBox的信号都引向同一个槽
        connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(anyStateChanged()));
    }

/*任何一个checkBox被点击时,共同的槽函数*/
void XXXXX::anyStateChanged()
{
    //qDebug() << "one checkBox State Changed";
    selectedItems.clear();
    //遍历所有的CheckBox,把所有选中的CheckBox索引号都记录到QStringList selectedItems中
    for(int i = 0; i < ui->listWidget->count(); i++)
    {        
        QListWidgetItem *item = ui->listWidget->item(idx);//先获取QListWidgetItem
        QCheckBox *checkBox = static_cast<QCheckBox *>(ui->listWidget->itemWidget(item));//找到第i个Item对应的CheckBox
        if(checkBox->isChecked())
            selectedItems.append(i);
    }    
}

需要注意的是,任何一个CheckBox被点击都会触发anyStateChanged()这个槽函数,进行遍历所有CheckBox,如果用户点击了全选,那岂不是在一瞬间要遍历N多遍,这样做太低效,我的做法是,点击全选或者全不选时,用disConnect解除Click信号与anyStateChanged()槽的connect,然后自己构建编号的List并emit出去,然后再重新connect他们。

注意上面的ui->listWidget->setItemWidget(item, checkBox),其实我们不仅能向QLishWidget里面放置CheckBox,任何QWidget都可以放,我们可以自定义一个QWidget,里面包含好几个基本控件,然后把这个含有多个基本控件的自定义的Widget一并放到QLishWidget的每一个item里去。

我的一个项目的应用场景中,不仅要支持多选,还要实时显示每一项的数值,效果如下:


代码已上传到CSDN,下载链接见评论
 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章