C++ 动态生成的QTreeWidget中的父依赖QTreeWidgetItem复选框
我正在编写一个应用程序,它有一个QTreeWidget,通过解析包含树级别的XML文件来填充它。如果我选中了一个顶级复选框,我需要同时选中所有的次级复选框C++ 动态生成的QTreeWidget中的父依赖QTreeWidgetItem复选框,c++,checkbox,qt4,c++11,qtreewidget,C++,Checkbox,Qt4,C++11,Qtreewidget,我正在编写一个应用程序,它有一个QTreeWidget,通过解析包含树级别的XML文件来填充它。如果我选中了一个顶级复选框,我需要同时选中所有的次级复选框 我已经让XML解析器工作并用带有复选框但只能单独选中的QTreeWidgetItems填充QTreeWidget 要做到这一点,请保留必须使用XML生成树的代码。然后连接到itemChanged()信号并更新插槽中的检查状态。它应该看起来像: connect(treeWidget, SIGNAL(itemChanged(QTreeWidget
我已经让XML解析器工作并用带有复选框但只能单独选中的QTreeWidgetItems填充QTreeWidget 要做到这一点,请保留必须使用XML生成树的代码。然后连接到itemChanged()信号并更新插槽中的检查状态。它应该看起来像:
connect(treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
this, SLOT(updateChecks(QTreeWidgetItem*, int)));
void ClassName::updateChecks(QTreewidgetItem* item, int column)
{
// Checkstate is stored on column 0
if(column != 0)
return;
recursiveChecks(item);
}
void ClassName::recursiveChecks(QTreeWidgetItem* parent)
{
Qt::CheckState checkState = parent->checkState(0);
for(int i = 0; i < parent->childCount(); ++i)
{
parent->child(i)->setCheckState(0, checkState);
recursiveChecks(parent->child(i));
}
}
connect(treeWidget,信号(itemChanged(QTreeWidgetItem*,int)),
这个插槽(updateChecks(QTreeWidgetItem*,int));
void ClassName::updateChecks(QTreewidgetItem*item,int列)
{
//Checkstate存储在列0上
如果(列!=0)
返回;
递归检查(项目);
}
void ClassName::recursiveChecks(QTreeWidgetItem*父项)
{
Qt::CheckState CheckState=parent->CheckState(0);
对于(int i=0;ichildCount();++i)
{
父->子(i)->设置检查状态(0,检查状态);
递归检查(父->子(i));
}
}
需要考虑的几个注意事项:
我只是在这方面做了一些工作,根据瑞克的回答,我得到了很好的结果。也许它可以帮助其他人。 它仅为父对象更新父对象和子对象的三态状态(选中、未选中、部分选中)
void ClassName::updateChecks(QTreeWidgetItem*item,int列)
{
布尔差=假;
if(列!=0&&column!=-1)
返回;
if(item->childCount()!=0&&item->checkState(0)!=Qt::PartiallyChecked&&column!=-1){
Qt::CheckState CheckState=item->CheckState(0);
对于(int i=0;ichildCount();++i){
项->子项(i)->设置检查状态(0,检查状态);
}
}else if(item->childCount()==0 | |列==-1){
如果(项->父项()==0)
返回;
对于(int j=0;jparent()->childCount();++j){
如果(j!=item->parent()->indexOfChild(item)&&item->checkState(0)!=item->parent()->child(j)->checkState(0)){
diff=真;
}
}
if(diff)
item->parent()->setCheckState(0,Qt::PartiallyChecked);
其他的
item->parent()->setCheckState(0,item->checkState(0));
如果(项->父项()!=0)
updateChecks(项->父项(),-1);
}
}
不再需要recursiveChecks()。树状网络和updateChecks之间的连接仍然处于活动状态。这在搜索引擎中仍然很常见,并且已经过时。
只需在顶级项目上设置标志Qt::ItemIsAutoTristate。rabid,这是两件不同的事情:选中复选框(第1段)和选择项目(第2段)。你什么意思?瑞克,非常感谢你!我对C++和QT完全陌生,所以这是一个巨大的帮助。但是我有一个问题,如果
QTreeWidget
是Qt创建者/设计者表单的一部分,那么ClassName
应该是什么?它只是包含QMainWindow
的类名称吗?还有,recursiveChecks()
方法中的item
变量来自何处?不管怎样,我将它添加到我正在使用的QMainWindow
扩展类中,并在第二个方法中将item
更改为parent
。工作得很有魅力!!再次感谢@RabidWidget很高兴你找到了它…QMainWidget是一个放置我给你的代码的有效地方。祝你好运如果你使用的是现代Qt,这绝对是正确的答案。它的速度非常慢,有大量的项目。
void ClassName::updateChecks(QTreeWidgetItem *item, int column)
{
bool diff = false;
if(column != 0 && column!=-1)
return;
if(item->childCount()!=0 && item->checkState(0)!=Qt::PartiallyChecked && column!=-1){
Qt::CheckState checkState = item->checkState(0);
for (int i = 0; i < item->childCount(); ++i) {
item->child(i)->setCheckState(0, checkState);
}
} else if (item->childCount()==0 || column==-1) {
if(item->parent()==0)
return;
for (int j = 0; j < item->parent()->childCount(); ++j) {
if(j != item->parent()->indexOfChild(item) && item->checkState(0)!=item->parent()->child(j)->checkState(0)){
diff = true;
}
}
if(diff)
item->parent()->setCheckState(0,Qt::PartiallyChecked);
else
item->parent()->setCheckState(0,item->checkState(0));
if(item->parent()!=0)
updateChecks(item->parent(),-1);
}
}