13.7.1 QListWidget(1)
类QListWidget在其内部定义了一个具有列表结构的模型,并以列表形式显示其中的数据项。列表中的每个数据项被表示为类QListWidgetItem的一个对象。在列表视图中所要显示的数据被存放在每个数据项的角色DisplayRole对应的数据子项中。这个数据子项的类型为QVariant,其中可以存放类型为QString的字符串,也可以存放类型为int或者double的数值。我们可以调用QListWidget的成员函数addItem()向列表添加一个数据项。
如果列表中所要处理的数据是字符串类型,QListWidget提供了更简单的添加方式,如代码段13 29行①所示。QListWidget的成员函数addItems()将一个QStringList对象所含的全部元素添加到内部模型中,该函数将这些数据项中角色DisplayRole对应的数据子项设置为QString类型的,因而行②的排序操作会将"100"、"101"以及"102"排在"98"的前面。
代码段13 29,向QListWidget中添加数据项,取自z:\examples\mvc\QListWidget_demo\main.cpp
- QListWidget * left = new QListWidget();
- QStringList list;
- list << "98" << "99" << "100" << "101" << "102";
- left->addItems( list ); ①
- left->sortItems(); ②
-
- QListWidget * right = new QListWidget();
- for ( int i=98; i<103; i++) {
- QListWidgetItem * item = new QListWidgetItem; ③
- item->setData(Qt::DisplayRole, i); ④
- right->addItem(item);
- }
- right->sortItems(); ⑤
为了能够在数据项中存入数值类型的数据,我们可以像行③那样先创建一个QListWidgetItem对象,然后调用其setData()函数,显式地设置该数据项中角色DisplayRole对应的数据子项的值。该函数的第二个参数是QVariant类型,本例中的实参"i"会被转换为一个QVariant对象,该对象会纪录所存放的数据为整数类型。行⑤对列表中的数据项进行排序时,会将它们看作整数。
与普通模型中的数据项一样,QListWidgetItem所表示的数据项也包含多个『角色,数据子项』对。前面的例子仅演示和如何修改DisplayRole对应的数据子项,下面我们再举一个较复杂的例子,来演示如何更改其他数据子项,以使得QListWidget显示出来的列表具有更漂亮的外观、更强大的功能。
这个例子运行时的界面如13.2.1节图13 8所示,它在对话框的左侧显示2011年世界上10大新闻的标题以及图标。用户单击其中一个后,程序在右侧的上方显示该新闻的图片,下方显示英文版的新闻文字。如果用户将鼠标停留在列表中某个数据项的区域内,程序会显示中文版的新闻文字。
新闻的信息被存放在一个全局数组中,如代码段13 30所示。数组中每个元素的类型为结构体News_Info,其成员变量都是指向字符串的指针,分别指向新闻标题、新闻图片的文件名、中文版新闻文字、英文版新闻文字。
代码段13 30,新闻的表示,z:\examples\mvc\item_roles\NewsDialog.cpp
- typedef struct {
- char * news_title, * image_filename;
- char * news_in_Chinese, * news_in_English;
- } News_Info;
- News_Info news_2011[10] = {
- {"日本海啸", "images/Japan_Tsunami.jpg",
- "3月14日,日本岩手县大槌町,一艘船被冲到屋顶,四周被无数碎片包围......",
- "A tsunami-tossed boat rests on top of a building amid a sea of debris in Otsuchi……"},
- ……
- }
程序定义的类NewsDialog负责显示该例子的主界面,它是QDialog的子类。该类定义了以下私有数据成员:QListWidget * listWidget,所指对象表示界面左侧的列表;QLabel * image,所指对象负责显示界面右上方的新闻图片;QLabel * news,所指对象负责显示界面右下方的英文版新闻文字。得益于QLabel的设计,该类既可以显示一个图像,也可以显示一段文字。
在NewsDialog的构造函数中我们创建以上对象,如代码段13 31所示。行①创建一个列表视图,接下来的几行设置该视图对象的显示属性。行②创建一个QListWidgetItem对象,表示列表中的一个数据项,接下来的几行设置该数据项中各角色对应的数据子项。由于本例的一些字符串含有中文字符,而这些字符在笔者所用的VS 2010开发环境中是以GB 2312标准进行编码的,所以本例子需要在main()函数中调用:
- QTextCodec::setCodecForTr(QTextCodec::codecForName("GB2312")) ;