ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Qt 多元素控件详解:QListWidget、QTableWidget 与 QTreeWidget 实战指南

Qt 多元素控件详解:QListWidget、QTableWidget 与 QTreeWidget 实战指南 目录1. 多元素控件1.1 List Widget1.2 Table Widget1.3 Tree Widget2. 小结3. 经典面试题1.多元素控件Qt 中提供的多元素控件有:QListWidget和QListView(列表)QTableWidget和QTableView表格QTreeWidget和QTreeView树形结构xxWidget 和 xxView 之间的区别•QTableView是基于MVC设计的控件.QTableView⾃⾝不持有数据. 使⽤QTableView的时候需要⽤⼾创建⼀个Model对象 (⽐如QStandardModel), 并且把Model和QTableView关联起来. 后续修改Model中的数据就会影响QTableView的显⽰; 修改QTableView的显⽰也会影响到Model中的数据(双向绑定).•QTableWidget则是QTableView的⼦类, 对Model进⾏了封装. 不需要⽤⼾⼿动创建Model对象, 直接就可以往QTableWidget中添加数据了.‍♀️补充笔记xxView是更加底层的实现1.xxWidget是基于xxView封装而成的此时xxView是MVC结构的一种典型实现2.MVC也是软件开发中非常经典的软件结构的组织形式了3.M model数据 V view视图界面C controller控制器数据和视图之间的业务流程。4.此处的xxView只是负责实现了视图不负责数据如何存储表示更不负责数据和视图之间的交互。5.因此使用xxView就需要程序员自己实现model和controller的部分就比较麻烦。6.xxWidget基于xxView同时把model和controller都帮我们实现好了拿过来就可以直接使用人家提供了功能方便的api我们可以直接使用。1.1 List Widget使⽤QListWidget能够显⽰⼀个纵向的列表. 形如:每个选项都可以被选中。核⼼属性属性说明currentRow当前被选中的是第几行count一共有多少行sortingEnabled是否允许排序isWrapping是否允许换行itemAlignment元素的对齐方式selectRectVisible被选中的元素矩形是否可见spacing元素之间的间隔核⼼⽅法方法说明addItem(const QString label)列表中添加元素addItem(QListWidgetItem *item)列表中添加元素currentItem()返回QListWidgetItem*表示当前选中的元素setCurrentItem(QListWidgetItem* item)设置选中哪个元素setCurrentRow(int row)设置选中第几行的元素insertItem(const QString label, int row)在指定的位置插入元素insertItem(QListWidgetItem *item, int row)在指定的位置插入元素item(int row)返回QListWidgetItem*表示第 row 行的元素takeItem(int row)删除指定行的元素返回QListWidgetItem*表示是哪个元素被删除了核⼼信号信号说明currentItemChanged(QListWidgetItem* current, QListWidgetItem* old)选中不同元素时会触发参数是当前选中的元素和之前选中的元素currentRowChanged(int)选中不同元素时会触发参数是当前选中元素的行数itemClicked(QListWidgetItem* item)点击某个元素时触发itemDoubleClicked(QListWidgetItem* item)双击某个元素时触发itemEntered(QListWidgetItem* item)鼠标进入元素时触发在上述介绍中, 涉及到⼀个关键的类,QListWidgetItem.这个类表⽰QListWidget中的⼀个元素.核⼼⽅法如下, 本质上就是⼀个 “⽂本图标” 构成的.方法说明setFont(const QFont font)设置字体setIcon(const QIcon icon)设置图标setHidden(bool hide)设置隐藏setSizeHint(const QSize size)设置尺寸setSelected(bool select)设置是否选中setText(const QString text)设置文本setTextAlignment(int alignment)设置文本对齐方式代码⽰例: 使⽤ListWidget在界⾯上创建⼀个ListView, 右键 -变形为 -ListWidget, 再创建⼀个lineEdit和 两个按钮.注意:ListWidget 是ListView的⼦类, 功能⽐ListView更丰富. 咱们使⽤ListWidget即可.2) 编写widget.cpp, 在构造函数中添加初始元素,并编写listWidget的slot函数#includewidget.h#includeui_widget.h#includeQDebugWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);//初始化listWightui-listWidget-addItem(Java);ui-listWidget-addItem(C);ui-listWidget-addItem(Python);ui-listWidget-addItem(PHP);ui-listWidget-addItem(GoLang);}Widget::~Widget(){deleteui;}voidWidget::on_listWidget_currentItemChanged(QListWidgetItem*current,QListWidgetItem*previous){//此处需要先判断current和 previous非空初始情况下是没有元素被选中的就导致这两指针可能为空if(current!NULLprevious!NULL){qDebug()当前选中current-text()之前选中previous-text();}}注意这⾥需要给widget.h前⾯加上#include QListWidgetItem,此处的wight.cpp文件中就不需要再加头文件了。编写按钮的slot函数voidWidget::on_pushButton_clicked(){//获取到输入框lineEdit中的内容constQStringtextui-lineEdit-text();if(text.isEmpty()){return;}ui-listWidget-addItem(text);}voidWidget::on_pushButton_2_clicked(){//获取当前被选中的元素introwui-listWidget-currentRow();//删除这一行元素ui-listWidget-takeItem(row);}执⾏程序, 观察效果. 可以新增元素, 选中元素, 删除元素.1.2 Table Widget使⽤QTableWidget表⽰⼀个表格控件. ⼀个表格中包含若⼲⾏, 每⼀⾏⼜包含若⼲列.表格中的每个单元格, 是⼀个QTableWidgetItem对象.QTableWidget核⼼⽅法方法说明item(int row, int column)根据行数列数获取指定的QTableWidgetItem*setItem(int row, int column, QTableWidgetItem*)根据行数列数设置表格中的元素currentItem()返回被选中的元素QTableWidgetItem*currentRow()返回被选中元素是第几行currentColumn()返回被选中元素是第几列row(QTableWidgetItem*)获取指定 item 是第几行column(QTableWidgetItem*)获取指定 item 是第几列rowCount()获取行数columnCount()获取列数insertRow(int row)在第 row 行处插入新行insertColumn(int column)在第 column 列插入新列removeRow(int row)删除第 row 行removeColumn(int column)删除第 column 列setHorizontalHeaderItem(int column, QTableWidgetItem*)设置指定列的表头setVerticalHeaderItem(int row, QTableWidgetItem*)设置指定行的表头QTableWidgetItem核⼼信号信号说明cellClicked(int row, int column)点击单元格时触发cellDoubleClicked(int row, int column)双击单元格时触发cellEntered(int row, int column)鼠标进入单元格时触发currentCellChanged(int row, int column, int previousRow, int previousColumn)当前选中单元格变化时触发参数是当前单元格的行列和之前单元格的行列QTableWidgetItem核⼼⽅法方法说明row()获取当前是第几行当前选中的行和列前一次选中的行和列column()获取当前是第几列setText(const QString)设置文本setTextAlignment(int)设置文本对齐setIcon(const QIcon)设置图标setSelected(bool)设置被选中setSizeHint(const QSize)设置尺寸setFont(const QFont)设置字体代码⽰例: 使⽤QTableWidget在界⾯上创建QTableWidget和 四个按钮, 一个输⼊框 注意:QTableWidget是QTableView的⼦类, 功能⽐QTableView更丰富. 咱们使⽤QTableWidget即可.2) 编写 widget.cpp 构造函数, 构造表格中的初始数据.#includewidget.h#includeui_widget.h#incldueQTableWightItemWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);//创建5行ui-tableWidget-insertRow(0);ui-tableWidget-insertRow(1);ui-tableWidget-insertRow(2);ui-tableWidget-insertRow(3);ui-tableWidget-insertRow(4);//创建3列ui-tableWidget-insertColumn(0);ui-tableWidget-insertColumn(1);ui-tableWidget-insertColumn(2);//给三列设定列名ui-tableWidget-setHorizontalHeaderItem(0,newQTableWidgetItem(学号));ui-tableWidget-setHorizontalHeaderItem(0,newQTableWidgetItem(姓名));ui-tableWidget-setHorizontalHeaderItem(0,newQTableWidgetItem(年龄));//设置初始值ui-tableWidget-setItem(0,0,newQTableWidgetItem(1001));ui-tableWidget-setItem(0,1,newQTableWidgetItem(张三));ui-tableWidget-setItem(0,2,newQTableWidgetItem(20));ui-tableWidget-setItem(1,0,newQTableWidgetItem(1002));ui-tableWidget-setItem(1,1,newQTableWidgetItem(李四));ui-tableWidget-setItem(1,2,newQTableWidgetItem(21));ui-tableWidget-setItem(2,0,newQTableWidgetItem(1003));ui-tableWidget-setItem(2,1,newQTableWidgetItem(王五));ui-tableWidget-setItem(2,2,newQTableWidgetItem(19));}Widget::~Widget(){deleteui;}编写按钮的slot函数//新增一行voidWidget::on_pushButton_clicked(){//1.获取到行数introwCountui-tableWidget-rowCount();//2.插入新行ui-tableWidget-insertRow(rowCount);}//删除对应行voidWidget::on_pushButton_2_clicked(){//1.获取到选中的行号intcurRowui-tableWidget-currentRow();//2.删除对应行ui-tableWidget-removeRow(curRow);}//新增一列voidWidget::on_pushButton_3_clicked(){//1.获取到列数intcolCountui-tableWidget-columnCount();//2.插入新列ui-tableWidget-insertColumn(colCount);//3.设置列名constQStringnameui-lineEdit-text();ui-tableWidget-setHorizontalHeaderItem(colCount,newQTableWidgetItem(name));}//删除对应列voidWidget::on_pushButton_4_clicked(){//1.获取选中的列号intcurColui-tableWidget-currentColumn();//2.删除对应的列ui-tableWidget-removeColumn(curCol);}执⾏程序, 即可完成表格的基本操作.注意默认情况下, 单元格中的内容直接就是可编辑的.如果不想让⽤⼾编辑,可以设置ui-tableWidget-setEditTriggers(QAbstractItemView::NoEditTriggers);1.3 Tree Widget使⽤QTreeWidget表⽰⼀个树形控件. ⾥⾯的每个元素, 都是⼀个QTreeWidgetItem, 每个QTreeWidgetItem可以包含多个⽂本和图标, 每个⽂本/图标为⼀个 列.可以给QTreeWidget设置顶层节点(顶层节点可以有多个), 然后再给顶层节点添加⼦节点, 从⽽构成树形结构.QTreeWidget核⼼⽅法方法说明clear()清空所有子节点addTopLevelItem(QTreeWidgetItem* item)新增顶层节点topLevelItem(int index)获取指定下标的顶层节点topLevelItemCount()获取顶层节点个数indexOfTopLevelItem(QTreeWidgetItem* item)查询指定节点是顶层节点中的下标takeTopLevelItem(int index)删除指定的顶层节点返回QTreeWidgetItem*表示被删除的元素currentItem()获取到当前选中的节点返回QTreeWidgetItem*setCurrentItem(QTreeWidgetItem* item)选中指定节点setExpanded(bool)展开/关闭节点setHeaderLabel(const QString text)设置 TreeWidget 的 header 名称QTreeWidget核⼼信号信号说明currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* old)切换选中元素时触发itemClicked(QTreeWidgetItem* item, int col)点击元素时触发itemDoubleClicked(QTreeWidgetItem* item, int col)双击元素时触发itemEntered(QTreeWidgetItem* item, int col)鼠标进入时触发itemExpanded(QTreeWidgetItem* item)元素被展开时触发itemCollapsed(QTreeWidgetItem* item)元素被折叠时触发QTreeWidgetItem核⼼属性属性说明text持有的文本textAlignment文本对齐方式icon持有的图标font文本字体hidden是否隐藏disabled是否禁用expand是否展开sizeHint尺寸大小selected是否选中QTreeWidgetItem核⼼⽅法方法说明addChild(QTreeWidgetItem* child)新增子节点childCount()子节点的个数child(int index)获取指定下标的子节点返回QTreeWidgetItem*takeChild(int index)删除对应下标的子节点removeChild(QTreeWidgetItem* child)删除对应的子节点parent()获取该元素的父节点代码⽰例: 使⽤QTreeWidget在界⾯上创建⼀个TreeView, 右键 选择 变形为TreeWidget, 再创建⼀个lineEdit和 两个按钮.注意:TreeWidget是TreeView的⼦类, 功能⽐TreeView更丰富. 咱们使⽤TreeWidget即可.ui-treeWidget-setHeaderLabel(动物);QTreeWidgetItem*item1newQTreeWidgetItem();item1-setText(0,猫);ui-treeWidget-addTopLevelItem(item1);QTreeWidgetItem*item2newQTreeWidgetItem();item1-setText(1,猫);ui-treeWidget-addTopLevelItem(item2);QTreeWidgetItem*item3newQTreeWidgetItem();item1-setText(2,猫);ui-treeWidget-addTopLevelItem(item3);编写代码, 实现按钮的slot函数voidWidget::on_pushButton_clicked(){//获取lineEdit中需要加入到顶层TreeWidget中constQStringtextui-lineEdit-text();if(text.isEmpty())return;//添加到顶层节点QTreeWidgetItem*itemnewQTreeWidgetItem();item-setText(0,text);ui-treeWidget-addTopLevelItem(item);}//把新节点添加为选中节点的子节点voidWidget::on_pushButton_2_clicked(){//获取到当前选中的节点constQStringtextui-lineEdit-text();if(text.isEmpty()){return;}//获取到当前选中的节点QTreeWidgetItem*current_itemui-treeWidget-currentItem();if(current_itemNULL)return;//构造新的itemQTreeWidgetItem*new_itemnewQTreeWidgetItem();new_item-setText(0,text);//添加item到选中节点current_item-addChild(new_item);//展开父节点current_item-setExpanded(true);}voidWidget::on_pushButton_3_clicked(){//获取到当前选中的节点QTreeWidgetItem*cur_itemui-treeWidget-currentItem();if(cur_itemNULL)return;//获取当前节点的父节点QTreeWidgetItem*parentcur_item-parent();if(parentNULL){//获取顶层节点的索引然后删除intindexui-treeWidget-indexOfTopLevelItem(cur_item);ui-treeWidget-takeTopLevelItem(index);}else{//非顶层节点parent-removeChild(cur_item);}}执⾏程序, 可以针对树形框进⾏编辑.笔记上述三个控件相关的操作数据都是再内存中保存的无论在界面上做任何操作重新运行程序之前的数据都没了如果想要数据能够重新启动也不丢失就需要编写更多的代码把内存中存储的数据获取到然后写入到文件中并且下次运行的时候从文件中加载数据。 2.小结本文介绍了 Qt 中三种常用的多元素控件QListWidget列表、QTableWidget表格和QTreeWidget树形结构。它们分别对应QListView、QTableView和QTreeView的封装子类基于MVC架构设计但xxWidget系列已经将Model和Controller封装好开箱即用无需手动创建Model对象。每个控件都围绕「核心属性、核心方法、核心信号、元素类Item」四个维度展开QListWidget纵向列表元素为QListWidgetItem支持增删、选中、排序等操作。QTableWidget表格控件元素为QTableWidgetItem支持按行列增删、设置表头、编辑单元格等操作。QTreeWidget树形控件元素为QTreeWidgetItem支持顶层节点与子节点的增删、展开/折叠等操作。三者共同点是数据都保存在内存中程序重启后数据会丢失若需持久化需自行将数据写入文件并在启动时加载。 3.经典面试题1.QListWidget和QListView有什么区别答QListView是基于MVC设计的底层控件自身不持有数据需要用户创建Model对象并与之关联QListWidget是QListView的子类对Model进行了封装无需手动创建Model直接调用addItem()等方法即可添加数据使用更简单。2.QTableWidget如何新增一行答先调用rowCount()获取当前行数再调用insertRow(rowCount)在末尾插入新行。示例代码如下introwCountui-tableWidget-rowCount();ui-tableWidget-insertRow(rowCount);3. 如何禁止用户编辑QTableWidget的单元格答默认情况下单元格内容是可编辑的。可以通过设置编辑触发器来禁止ui-tableWidget-setEditTriggers(QAbstractItemView::NoEditTriggers);4.QTreeWidget中如何区分顶层节点和子节点答可以通过parent()方法判断。如果parent()返回NULL说明该节点是顶层节点否则返回的是其父节点说明它是子节点。删除节点时顶层节点用takeTopLevelItem(index)子节点用removeChild(child)。5.QListWidget中如何获取当前选中的元素答调用currentItem()返回QListWidgetItem*表示当前选中的元素调用currentRow()返回当前选中元素的行号。删除选中元素时可结合takeItem(row)使用。6.QTableWidget中如何获取当前选中的单元格位置答调用currentRow()获取当前选中元素的行号调用currentColumn()获取列号。若需获取选中的QTableWidgetItem*调用currentItem()。7.QTreeWidgetItem如何添加子节点答调用addChild(QTreeWidgetItem* child)方法。示例QTreeWidgetItem*new_itemnewQTreeWidgetItem();new_item-setText(0,子节点);current_item-addChild(new_item);current_item-setExpanded(true);// 展开父节点8. 为什么xxWidget比xxView更常用答xxView是更底层的实现只负责视图显示不负责数据存储和交互需要程序员自己实现Model和Controller比较麻烦xxWidget基于xxView封装把Model和Controller都实现好了提供了方便的 API开箱即用因此更常用。9. 三个控件的数据在程序重启后还在吗答不在。三个控件的数据都保存在内存中程序重启后数据会丢失。若需持久化需要编写代码将内存中的数据写入文件并在下次启动时从文件加载
返回列表