当前位置: 首页>编程语言>正文

qtreewidgetitem属性 qt qtreewidgetitem

        作者:奇先生        

8.3.2 QTreeWidgetItem

树形控件条目的内容是最复杂的,因为每一个条目涉及到内部多列数据的操作、父子节点操作,这些都是之前列表控件条目和表格控件条目不具备的特性。我们 首先介绍树形 控件条目的构造函数,然后按父子节点操作、通用数据操作和非通用数据操作三方面介绍树形控件条目。

(1)构造函数和复制函数

QTreeWidgetItem 构造函数较多,首先看不带父对象指针的构造函数:

QTreeWidgetItem(int type = Type)

QTreeWidgetItem(const QStringList & strings, int type = Type)

QTreeWidgetItem(const QTreeWidgetItem & other)

类型 type 一般用于派生类的自定义条目类型,基本用不到。第二个构造函数字符串列表 strings 就是条目内多列的文本,类似把表格控件一整行的多列文本塞到一个条目内部了。第三个是复制构造函数,复制时除了 type()、treeWidget()、parent(),其他的都复制。
克隆函数:

QTreeWidgetItem * QTreeWidgetItem::clone() const

clone()是按照本条目一模一样造出一个新的条目,是深拷贝,与本条目(包括子孙节点)不共享内存,函数返回的新条目也没有复制 type()、treeWidget()、parent() ,新条目是自由的,没归属。clone() 函数会克隆所有的子孙节点,并且新子孙节点之间的关系也一样,QTreeWidgetItem 源码中 使用压栈出栈 方式实现了子孙节点的遍历复制。
赋值 "=" 函数:

QTreeWidgetItem & operator=(const QTreeWidgetItem & other)

 等于号函数与克隆函数有本质区别,它只拷贝 other 这一个节点内的数据到本节点里,包括显示的字符串和多列数据、标志位等,type() 和 treeWidget()、parent()的内容不会修改。等于号函数不涉 及任何子孙节 点,也不改变隶属的父节点。
顺便提一下小于号函数:

virtual bool operator<(const QTreeWidgetItem & other) const

字典序比较大小,否则都按照第0列的文本比较。

(2)父子节点操作

条目查看父节点的指针使用函数:

QTreeWidgetItem * QTreeWidgetItem::parent() const  //常量,子节点不能改父节点指针

注意子节点是不能修改父节点指针的,只能父节点换子节点,不能子节点换父节点。

最常用的是节点控制自己的直接子节点,添加子节点使用函数:

void addChild(QTreeWidgetItem * child) //添加一个子节点到末尾

void addChildren(const QList<QTreeWidgetItem *> & children) //添加多个子节点末尾

void insertChild(int index, QTreeWidgetItem * child) //插入子节点序号 index 序号位置

void insertChildren(int index, const QList<QTreeWidgetItem *> & children)//插入多个子节点到 index 位置

直接子节点的计数(与孙辈或更低辈分的节点数目无关)用如下函数:

int childCount() const

根据序号获取直接子节点的指针使用函数(如果序号超界返回NULL):

QTreeWidgetItem * child(int index) const  //序号查子节点指针

反过来,根据子节点指针查序号的函数如下(如果查不到序号返回-1):

int indexOfChild(QTreeWidgetItem * child) const

移除子节点使用如下函数:

void removeChild(QTreeWidgetItem * child)  //根据子节点指针解除父子关系

QTreeWidgetItem * takeChild(int index)  //根据子节点序号解除父子 关系,返回卸下后的自由节点指针

QList<QTreeWidgetItem *> takeChildren()  //卸下所有子节点

注意这几个函数只是解除父子关系,卸下的子节点还存在内存中,如果要完全删除需要手动 delete  每个节点。
当节点有隶属的树形控件时,可以使用下面函数对子节点排序:

void sortChildren(int column, Qt::SortOrder order)  // 根据指定列号column排序,升序或降序由order指定

如果条目不属于任何树形控件,那么该排序函数无效。

条目还可以控制自己的子节点指示器(条目显示时左边的加号 +)如何显示:

QTreeWidgetItem::ChildIndicatorPolicy childIndicatorPolicy() const //获取子节点指示器显示策略

void QTreeWidgetItem::setChildIndicatorPolicy(QTreeWidgetItem::ChildIndicatorPolicy policy) //设置子节点指示器显示策略

子节点指示器显示策略 QTreeWidgetItem::ChildIndicatorPolicy 有三种:

ChildIndicatorPolicy 枚举常量

数值

描述

QTreeWidgetItem::ShowIndicator

0

无论有无子节点都显示指示符。

QTreeWidgetItem::DontShowIndicator

1

始终不显示指示符。

QTreeWidgetItem::DontShowIndicatorWhenChildless

2

条目有子节点就显示指示符,没子节点就不显示。

默认值是最后一个,有子节点就显示指示符,没有子节点就不显示指示符,这种方式也最为科学,一般不需要改指示符显示策略。

关于父子节点操作函数介绍到这,这些函数的特点就是只处理直接的子节点,与孙子辈、更低辈分节点无关,孙子辈由儿子辈去管理,以此类推,族谱树中各层节点只管理亲儿子,其他辈分都不管。 递归操作 就是这样,只管处理儿子辈代码,孙子辈的由儿子辈去管,层层下推,就是递归的过程。

(3)通用数据操作

通用数据一般是用于 QDataStream 保存条目的信息到文件中,也可以从文件中加载通用数据生成以前的树。树形控件条目的通用数据函数与前面章节列表条目、表格条目类似,但是多了指定列号的参数,因为每个属性条目有多列数据,每列数据有分多种角色,因此属性条目使用二维向量存储通用数据

// One item has a vector of column entries. Each column has a vector of (role, value) pairs.

    QVector< QVector<QWidgetItemData> > values;

对于通用数据的设置和读取,也有 data() 和 setData() 函数,只是多了列号:

QVariant QTreeWidgetItem::data(int column, int role) const

void QTreeWidgetItem::setData(int column, int role, const QVariant & value)

其他针对各个角色的读写函数如下表所示:

获取函数

设置函数

数据角色

描述

text(int column)

setText(int column, const QString &text)

Qt::DisplayRole

条目显示的文本。

icon(int column)

setIcon(int column, const QIcon &icon)

Qt::DecorationRole

条目显示的图标。

statusTip(int column)

setStatusTip(int column, const QString &statusTip)

Qt::StatusTipRole

如果主界面有状态栏,鼠标悬停在该条目上时显示该状态信息到状态栏。

toolTip(int column)

setToolTip(int column, const QString &toolTip)

Qt::ToolTipRole

鼠标悬停在该条目上时显示的工具提示信息。

whatsThis(int column)

setWhatsThis(int column, const QString &whatsThis)

Qt::WhatsThisRole

如果主界面窗口标题栏有?帮助按钮,点击帮助按钮再点击该条目会显示该帮助信息。

font(int column)

setFont(int column, const QFont &font)

Qt::FontRole

显示条目文本用的字体。

textAlignment(int column

setTextAlignment(int column, int alignment)

Qt::TextAlignmentRole

文本的对齐方式。

backgroundColor(int column)

setBackgroundColor(int column, const QColor &color)

Qt::BackgroundColorRole

文本背景色。

textColor(int column)

setTextColor(int column, const QColor &color)

Qt::TextColorRole

文字颜色。

background(int column)

setBackground(int column, const QBrush &brush)

Qt::BackgroundRole

条目的背景画刷。

foreground(int column)

setForeground(int column, const QBrush &brush)

Qt::ForegroundRole

条目的前景画刷。

checkState(int column)

setCheckState(int column, Qt::CheckState state)

Qt::CheckStateRole

条目自带的复选框选中状态,可以是三态复选框。

sizeHint(int column)

setSizeHint(int column, const QSize &size)

Qt::SizeHintRole

条目显示的建议尺寸。

 树形条目也有相应的数据流读写函数,就是用于读取或保存这些通用数据:

QDataStream &    operator<<(QDataStream & out, const QTreeWidgetItem & item) //外部函数,将条目写入数据流

QDataStream &    operator>>(QDataStream & in, QTreeWidgetItem & item) //外部函数,读取数据流中的条目数据

void QTreeWidgetItem::write(QDataStream & out) const //成员函数,将条目数据写入数据流

void QTreeWidgetItem::read(QDataStream & in) //成员函数,从数据流中读取条目数据

 运算符重载函数 operator<<() 和 operator>>() 本质就是调用上面的 write() 和read() 函数。

(4)非通用数据操作

条目在构造函数指定的类型可以用如下函数获取,这个类型是只读的:

int QTreeWidgetItem::type() const

在添加到树形控件之后,都可以用如下函数查看条目隶属的树形控件:

QTreeWidget * QTreeWidgetItem::treeWidget() const  //常量,节点不能自行更换隶属,要从树形控件增删节点

 程序运行时除了树形控件本身的 QTreeWidget::selectedItems() 可以判断选中条目,每个条目对象自己也有函数获取高亮选中状态或设置是否高亮选中:(默认情况 下,树形条目自身是否高亮选中与子孙条目的情况无关)

bool QTreeWidgetItem::isSelected() const

void QTreeWidgetItem::setSelected(bool select)

树形条目初始化时也有默认的标志位,并且运行时可以修改标志位:

Qt::ItemFlags QTreeWidgetItem::flags() const

void QTreeWidgetItem::setFlags(Qt::ItemFlags flags)

树形条目构造时的默认标志位如下: 

Qt::ItemIsSelectable
   |Qt::ItemIsUserCheckable
   |Qt::ItemIsEnabled
   |Qt::ItemIsDragEnabled
   |Qt::ItemIsDropEnabled

树形条目默认不能编辑,如果希望条目文本可以双击编辑,可以用下面一句代码:

item->setFlags( (item->flags()) | Qt::ItemIsEditable ); //双击条目会自动 开启文本编辑器

这个标志会对树形条目所有列的文本编辑都生效,开启后该条目每个列的数据都能双击编辑。对于开启 Qt::ItemIsEditable 标志位的条目,除了用户双击等操作启用编辑器,也可以用函数代码指定开启条目的某列数据编辑器:

void QTreeWidget::editItem(QTreeWidgetItem * item, int column = 0)

树形条目默认有 Qt::ItemIsUserCheckable 标志,可以复选,但是复选框默认却看不到,可以用下面代码真正地显示复选框:

item->setCheckState(0, Qt::Unchecked);  //显示第0列的复选框,要指定列号

树形条目的复选框状态很特殊:

如果不使用三态复选(默认情况),那么当前条目的复选状态与子孙条目复选状态无关。
如果开启树形条目的三态复选,那么当前条目的复选状态与子孙有关:

如果所有子孙勾选,那么父节点勾选 Qt::Checked;
    如果部分子孙勾选,那么父节点部分勾选 Qt::PartiallyChecked;
    如果所有子孙不勾选,那么父节点不勾选 Qt::Unchecked。

三态勾选其实是真正反映父子勾选关系的,如果用复选框,那么有子孙的节点应该用三态的,无子孙的叶子节点用二态的,并且应当将所有树形控件的条目都显 示复选框:

// 迭代器

    QTreeWidgetItemIterator it(ui->treeWidget);
    while (*it)
    {
        //取出当前条目
        QTreeWidgetItem *item = *it;
        if(item->childCount() > 0 )//有子节点开启三态复选,没子节点是二态复选
        {
            item->setFlags( item->flags() | Qt::ItemIsTristate );
        }
        item->setCheckState(0, Qt::Unchecked);  //正常应该只用第0列的复选框,代表一整行条目
        //找下一个条目
        ++it;
    }

迭代器 QTreeWidgetItemIterator 专门用于遍历树形控件或某个父节点的所有子孙条目,因为树形结构是分叉结构,不同于列表控件的一维遍历,也不同于表格控件的二维遍历,因此需要迭代器或递归算法来穷举子孙 条目,下面小节专门介绍这些内容。


https://www.xamrdz.com/lan/5ev1944375.html

相关文章: