[QT_008]Qt学习之QListWidgetItem详解
本文转自:《Qt编程指南》 作者:奇先生
Qt编程指南,Qt新手教程,Qt Programming Guide
8.1.2 QListWidgetItem
QListWidgetItem 专门用于表示列表控件 QListWidget 的数据条目,注意: QListWidgetItem 是一个纯数据类,不是控件,没有基类,也就没有信号和槽函数。QListWidgetItem 可以直接用数据流 QDataStream 读写。
QListWidgetItem 不单单有字符串,还可以有自己的图标、复选框等特性,列表控件会根据条目对象的丰富特性来呈现数据并进行交互操作。
(1)首先来看看列表控件条目的构造函数:
QListWidgetItem(QListWidget * parent = 0, int type = Type)
QListWidgetItem(const QString & text, QListWidget * parent = 0, int type = Type)
QListWidgetItem(const QIcon & icon, const QString & text, QListWidget * parent = 0, int type = Type)
那第三个构造函数的参数来讲,icon 是条目显示的图标,text 是条目文本,parent 是条目隶属的列表控件,type 是条目的自定义类型。
如果在构造函数指定了条目隶属的列表控件,那么这个条目会自动添加到列表控件末尾,而不需要调用列表控件的 add*() 和 insert*()函数,比如:
new QListWidgetItem(tr("Hazel"), listWidget);
只需要上面一句代码,"Hazel" 条目就自动显示在列表控件 listWidget 里面了,只要指定所隶属的列表控件,新建的条目自动添加并显示在末尾。
(2)条目的复制方式,有三个函数可以实现:
QListWidgetItem(const QListWidgetItem & other) //复制构造函数
QListWidgetItem & operator=(const QListWidgetItem & other) // = 赋值函数
virtual QListWidgetItem * clone() const //克隆函数
复制构造函数和 "=" 赋值函数 函数原理是一样的,它们除了 type() 和 listWidget() 函数指定的两个数据不复制,其他的数据都复制。type() 是条目的自定义类型,listWidget() 是该条目所隶属的列表控件。
而克隆函数 clone() 会精确复制所有数据,如果原条目隶属某个列表控件,克隆出来的也会自动隶属该列表控件,自定义条目类型也一样。
顺便说一下列表条目的比较函数:
virtual bool operator<(const QListWidgetItem & other) const
只有一个小于号函数,是比较列表条目文本的字典序先后关系,没有等于号函数和大于号函数,如果确实用到条目文本比较,建议直接用 QString 变量进行比较。
(3)QListWidgetItem 的功能函数与内部数据
QListWidgetItem 绝大部分的功能函数都是围绕内部数据处理的,QListWidgetItem 内部的数据大致分为两类:第一类是以数据角色形式管理的通用数据,这些数据自动参与 QDataStream 数据流的读写;第二类是非通用数据,不参与数据流读写,与 QListWidgetItem 和 QListWidget 自身特性有关。
● 第一类:QListWidgetItem 的通用数据
通用数据是以数据角色与数据变量一一对应的形式存储管理,比如设置文本 setText()、设置图标 setIcon() 等函数,其本质都是根据各自的角色调用通用设置数据的函数:
virtual void setData(int role, const QVariant & value)
也可以根据角色来获取各个数据变量:
virtual QVariant data(int role) const
查看列表控件源码文件:
C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\widgets\itemviews\qlistwidget.h
可以看到关于文本变量的函数 text() 和 setText() 源代码:
inline QString text() const
{ return data(Qt::DisplayRole).toString(); }
inline void QListWidgetItem::setText(const QString &atext)
{ setData(Qt::DisplayRole, atext); }
关于 QListWidgetItem 内部通用数据的获取和设置函数、数据角色列表如下:
获取函数 | 设置函数 | 数据角色 | 描述 |
text() | setText(const QString &text) | Qt::DisplayRole | 条目显示的文本。 |
icon() | setIcon(const QIcon &icon) | Qt::DecorationRole | 条目显示的图标。 |
statusTip() | setStatusTip(const QString &statusTip) | Qt::StatusTipRole | 如果主界面有状态栏,鼠标悬停在该条目上时显示该状态信息到状态栏。 |
toolTip() | setToolTip(const QString &toolTip) | Qt::ToolTipRole | 鼠标悬停在该条目上时显示的工具提示信息。 |
whatsThis() | setWhatsThis(const QString &whatsThis) | Qt::WhatsThisRole | 如果主界面窗口标题栏有?帮助按钮,点击帮助按钮再点击该条目会显示该帮助信息。 |
font() | setFont(const QFont &font) | Qt::FontRole | 显示条目文本用的字体。 |
textAlignment() | setTextAlignment(int alignment) | Qt::TextAlignmentRole | 文本的对齐方式。 |
backgroundColor() | setBackgroundColor(const QColor &color) | Qt::BackgroundColorRole | 文本背景色。 |
textColor() | setTextColor(const QColor &color) | Qt::TextColorRole | 文字颜色。 |
background() | setBackground(const QBrush &brush) | Qt::BackgroundRole | 条目的背景画刷。 |
foreground() | setForeground(const QBrush &brush) | Qt::ForegroundRole | 条目的前景画刷。 |
checkState() | setCheckState(Qt::CheckState state) | Qt::CheckStateRole | 条目自带的复选框选中状态,可以是三态复选框。 |
sizeHint() | setSizeHint(const QSize &size) | Qt::SizeHintRole | 条目显示的建议尺寸。 |
QListWidgetItem 可以直接用数据流 QDataStream 读写,涉及到读写的内部数据就是上表所列举的以角色形式表述的数据,QListWidgetItem 通过两个外部全局运算符重载函数支持 QDataStream 数据流读写:
QDataStream &operator<<(QDataStream &out, const QListWidgetItem &item)
QDataStream &operator>>(QDataStream &in, QListWidgetItem &item)
使用运算符的形式比较方便,当然也可以用 QListWidgetItem 内部的读写函数:
void QListWidgetItem::read(QDataStream & in)
void QListWidgetItem::write(QDataStream & out) const
QListWidgetItem 内部采用私有的 QVector 向量存储通用数据的 role 和 value 对:
QVector<QWidgetItemData> values;
条目通用数据的读写就是读写私有向量 values,其中 QWidgetItemData 内部包含 role 和 value 成员变量:
class QWidgetItemData
{
public:
inline QWidgetItemData() : role(-1) {}
inline QWidgetItemData(int r, QVariant v) : role(r), value(v) {}
int role;
QVariant value;
inline bool operator==(const QWidgetItemData &other) const { return role == other.role && value == other.value; }
};
在 8.2 节表格控件的单元格条目也是类似的私有向量存储 role 和 value 对。
● 第二类:QListWidgetItem 的非通用数据
条目自定义类型:
int QListWidgetItem::type() const
这个条目类型只能在构造函数指定,指定之后不能修改,默认值为 QListWidgetItem::Type (数值 0),如果程序员希望自己区分列表控件条目的类型,那么可以自己定义大于 QListWidgetItem::UserType (数值 1000)的类型值,一般用在 QListWidgetItem 派生类里面。
条目所隶属的列表控件:
QListWidget * QListWidgetItem::listWidget() const
条目自身不能修改所隶属的列表控件,要通过列表控件的删除函数 QListWidget::takeItem(int row) 才能解除隶属关系。
列表条目本身的选中状态(与复选框无关,是用户在列表控件点击条目的高亮选中状态):
void QListWidgetItem::setSelected(bool select)
bool QListWidgetItem::isSelected() const
一般是用户在列表控件图形界面点击哪个条目,哪个条目就处于高亮选中状态,这里可以用条目自身的函数设置高亮选中状态。
条目在列表控件里面显示或者隐藏:
void QListWidgetItem::setHidden(bool hide)
bool QListWidgetItem::isHidden() const
条目的特性标志:
void QListWidgetItem::setFlags(Qt::ItemFlags flags)
Qt::ItemFlags QListWidgetItem::flags() const
flags 会决定条目的工作特性,比如是否有三态复选框,是否在用户双击该条目时开启文本编辑器等等,Qt::ItemFlags 枚举值见下面表格:
Qt::ItemFlags 枚举常量 | 数值 | 描述 |
Qt::NoItemFlags | 0 | 不设置任何特性,条目会处于完全的不可用状态。 |
Qt::ItemIsSelectable | 1 | 条目本身可以被高亮选中。 |
Qt::ItemIsEditable | 2 | 条目可以被编辑,比如用户双击条目时自动启用文本编辑器。 |
Qt::ItemIsDragEnabled | 4 | 条目可以被拖拽出去。 |
Qt::ItemIsDropEnabled | 8 | 条目可以作为拖拽的目的地。 |
Qt::ItemIsUserCheckable | 16 | 条目可以有复选框,用户能勾选复选框。 |
Qt::ItemIsEnabled | 32 | 条目处于可用状态。 |
Qt::ItemIsTristate | 64 | 条目的复选框可以有三种勾选状态:选中、非选中、部分选中。 |
Qt::ItemNeverHasChildren | 128 | 条目不能有子条目(指树形控件)。 |
上表中的 Qt::ItemFlags 也适用于后面 8.2 节的表格控件条目和 8.3 节的树形控件条目,表格条目和树形条目也都有一样的条目标志位设置函数,功能与本节列表条目一样,参数也一样。
列表控件条目默认的特性标志为同时启用四个:
Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
按照默认标志位,列表条目是可以有复选框进行勾选的,调用 QListWidgetItem::setCheckState() 函数可以让列表条目的复选框显示出来。
如果要设置三态复选框,可以使用下面的代码:
item->setFlags( (item->flags()) | Qt::ItemIsTristate ); //开启三态复选
item->setCheckState( Qt::Unchecked ); //显示复选框
如果希望用户在双击条目时,自动开启条目文本的编辑器,可以用下面代码:
item->setFlags( (item->flags()) | Qt::ItemIsEditable ); //双击条目会自动 开启文本编辑器
因为可以设置条目的 Qt::ItemIsEditable 标志位,所以列表控件 QListWidget 的一对持续编辑器函数 openPersistentEditor() 和 closePersistentEditor() 一般不需要手动调用,直接设置条目自身的可编辑标志位就行了。
对于启用可编辑标志位的条目,如果希望通过代码开启条目的编辑,可以调用列表控件的 editItem() 函数来实现,而不需要使用一对开关持续编辑器函数那么麻烦:
void QListWidget::editItem(QListWidgetItem * item)
这里说明一下:列表条目本身是可以存储复选框的勾选状态数值,而条目显示的复选框是由列表控 件绘制并提供,列表条目自身不是控件,也不包含子控件。类似地,列表控件根据 Qt::ItemIsEditable 标志位检查是否需要为条目提供文本编辑器。
更多推荐
所有评论(0)