详解QTreeWidget隐藏节点的两种方式
作者:前行中的小猪
简述
关于QTreeWidget隐藏节点有两种方式,一种是直接隐藏,一种是间接隐藏,但是两种方式各有差异,下面请听具体解说。
方法一:直接隐藏式
Qt助手里面提供了QTreeWidgetItem::setHidden方法,我们可以调用setHide(false)直接隐藏当前item。但是调用此方法会隐藏该节点下面的所有子节点。
图 1-1:
我们通过图1-2看到,调用此方法会将自己所有的孩子节点都给隐藏了,如果有这种需求的直接调用此方法即可。
效果图 1-2:
方法二:间接隐藏式
此种方法间接地去把节点隐藏起来,实际上节点还是存在的,只不过肉眼不可见。通过尝试了很多种方法,最后找到了几种组合式调用,将节点悄悄藏起来了。
上代码:
// 这里我们默认树的节点只有一列; m_rootItem->setText(0, ""); m_rootItem->setSizeHint(0, QSize(1, 1)); Qt::ItemFlags flags = m_rootItem->flags(); m_rootItem->setFlags(flags | Qt::ItemNeverHasChildren);
如果我们初始化的时候就没给m_rootItem节点进行设置文本,那第一步就不需要清空文本了,如果是前期需要显示,但是后期想不显示,需要先清空节点本身的文本,然后我们给节点设置大小为(1, 1),至于为什么设置(1, 1)而不是(0, 0),后面会举例说明,因为我们设置了大小为(1, 1),但是设置之后我们发现该节点左侧的小箭头还是存在的,为了去除小箭头,我们需要再给节点加上 Qt::ItemNeverHasChildren标志,就是告诉节点,你没有孩子节点,不要去显示小箭头了。
我们看到图2-1中就是没有告诉节点没有孩子,结果节点是不显示了,小箭头还是显示,虽然我们设置了大小(1,1),其实已经很小了,节点本身应该是不可见了,但是你没告诉他没孩子,那他依然显示没毛病,所以我们需要再设置标志位Qt::ItemNeverHasChildren,显式地告诉该节点,你没有孩子,你的小箭头就收起来吧O(∩_∩)O。
效果图 2-1:
通过图2-2,我们看到小箭头确实消失了。我们看代码的最后两行,这里进行了测试,输出为false,说明实际上节点还是存在的,只是我们通过特殊的方法将它藏起来了。
效果图 2-2:
下面我们探讨一下为啥不直接将item的大小设置为(0, 0),我们直接看效果就好了。
注意:
下方我们把大小改为了(0, 0),我们来对比图2-3和图2-4,仔细看看有什么不同。
首先两张图的按钮操作代码是一样的,仔细看效果图2-3我们点击按钮,隐藏节点之后,整个树结构是没有问题的,我们再看下图2-4我们发现,树上的节点变多了,点击按钮之后,在上下拖拽滚动条时我们发现节点会有显示错乱的问题。
效果图 2-3
效果图 2-4
为什么代码一样,结果不一样呢,这是我们树上的节点不一样了,图2-5中我们操作的节点Root1上方还有一个Root0节点,且Root1的孩子节点不多,导致滚动条没有出来,我自己也是经过多次测试,出现上图2-4这种错乱的问题,需两个条件,一个是操作的节点Root1位于树的第一个根节点,第二是树上的节点数目足够多(出现滚动条),不一定是Root1节点的孩子节点多导致,Root2节点过多也会导致显示错乱的问题,所以通过多次测试,我们放弃大小(0, 0)这种方式,,改为(1, 1)即可正常显示。
有人问那(1, 0)或者(0, 1)可以吗?
经测试(1, 0)不行,(0, 1)可以,问题在高度不能为0,有兴趣的小伙伴可以自己进行一个测试,下方提供了源码。
如果小伙伴们在运用过程中使用了样式表或者给item设置了widget,出现了新的问题欢迎一起讨论交流。
效果图 2-5
效果图 2-6
代码之路 .h文件
#include <QtWidgets/QWidget> #include <QTreeWidget> #include <QToolButton> class MyTreeWidget : public QWidget { Q_OBJECT public: MyTreeWidget(QWidget *parent = Q_NULLPTR); private: void initWgt(); void initTreeData(); private slots: void onBtnClicked(); private: QTreeWidget* m_treeWgt; QToolButton* m_pBtnControl; QTreeWidgetItem* m_rootItem; };
.cpp文件
#include "MyTreeWidget.h" #include <QVBoxLayout> #include <QDebug> #pragma execution_character_set("utf-8") MyTreeWidget::MyTreeWidget(QWidget *parent) : QWidget(parent) { initWgt(); initTreeData(); } void MyTreeWidget::initWgt() { m_treeWgt = new QTreeWidget; m_treeWgt->setHeaderHidden(true); m_pBtnControl = new QToolButton; m_pBtnControl->setText("隐藏根节点"); QVBoxLayout* vLayout = new QVBoxLayout(this); vLayout->addWidget(m_treeWgt); vLayout->addWidget(m_pBtnControl); connect(m_pBtnControl, &QToolButton::clicked, this, &MyTreeWidget::onBtnClicked); } void MyTreeWidget::initTreeData() { QTreeWidgetItem* m_rootItem1 = new QTreeWidgetItem(m_treeWgt); m_rootItem1->setText(0, "Root0"); m_rootItem = new QTreeWidgetItem(m_treeWgt); m_rootItem->setText(0, "Root1"); QTreeWidgetItem* item1 = new QTreeWidgetItem(m_rootItem); item1->setText(0, "Node1"); QTreeWidgetItem* item2 = new QTreeWidgetItem(m_rootItem); item2->setText(0, "Node2"); QTreeWidgetItem* item21 = new QTreeWidgetItem(item2); item21->setText(0, "Node21"); QTreeWidgetItem* item22 = new QTreeWidgetItem(item2); item22->setText(0, "Node22"); QTreeWidgetItem* item3 = new QTreeWidgetItem(m_rootItem); item3->setText(0, "Node3"); QTreeWidgetItem* item31 = new QTreeWidgetItem(item3); item31->setText(0, "Node31"); QTreeWidgetItem* item32 = new QTreeWidgetItem(item3); item32->setText(0, "Node32"); for (int i = 0; i < 10; i++) { QTreeWidgetItem* item = new QTreeWidgetItem(m_rootItem); item->setText(0, "Node"); } m_rootItem->setExpanded(true); QTreeWidgetItem* itemTmp = new QTreeWidgetItem(m_treeWgt); itemTmp->setText(0, "Root2"); QTreeWidgetItem* itemTmp1 = new QTreeWidgetItem(itemTmp); itemTmp1->setText(0, "NodeTmp"); } void MyTreeWidget::onBtnClicked() { // 直接隐藏; // bool isHide = m_rootItem->isHidden(); // m_rootItem->setHidden(!isHide); // 间接隐藏; m_rootItem->setText(0, ""); m_rootItem->setSizeHint(0, QSize(0, 0)); Qt::ItemFlags flags = m_rootItem->flags(); m_rootItem->setFlags(flags | Qt::ItemNeverHasChildren); bool isHide = m_rootItem->isHidden(); qDebug() << isHide; }
结尾
以上是前段时间帮同事解决的一个小问题,其实问题很简单,解决的代码就那么几行,但是为了写这篇博客,我专门写了一个例子,进行了多次测试,结合各种参数对比和效果图,为的是希望看到的小伙伴能够更容易看懂和理解,本来一个小时可以写完的,为了详细点同时也为了验证正确性,防止小伙伴误解花了几个小时时间准备例子、测试结果及分析讲解,编码不易,写博客也是对自己的一个挑战,不论是耐心,还是细心。我觉得作为一个合格的程序员应该对自己有点要求,遇到问题我们需要自己不断地去进行验证,拓展,不能全信网上提供的资料,更多的是需要自己花时间研究,验证,将别人的内容能够更好地吸收。
到此这篇关于详解QTreeWidget隐藏节点的两种方式的文章就介绍到这了,更多相关QTreeWidget隐藏节点内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!