计算机系统应用教程网站

网站首页 > 技术文章 正文

实战PyQt5: 068-MV框架中的项视图部件

btikc 2024-10-20 05:05:29 技术文章 14 ℃ 0 评论

在Qt中,基于项的部件按照它们的用途进行了命名, QListWidget提供一个项的列表, QTreeWidget则显示多层次属性结构的部将项, QTableWidget提供表格样式的部件列表。

列表部件QListWidget

单层次列表项用一个QListWidget和一些QListWidgetItems来显示,列表部件的构造方式与其他部件相同:

         listWidget = QListWidget(self)

列表项可以在构造的时候直接直接添加到列表组件中:

         QListWidgetItem('Sycamore', listWidget)
         QListWidgetItem('Chestnut',listWidget)
         QListWidgetItem('Mahogany',listWidget)

列表项在构造时也可以不指定父列表部件,而是在之后添加到列表部件中:

         newItem=QListWidgetItem()
         newItem.setText(itemText)
         listWidget.insertItem(row, newItem)

列表里的每个项都可以显示文字标识和一个图标。可以更改用于渲染文本的颜色和字体,以提供项目的自定义外观。也可以设定工具提示信息,状态信息,以及“这是什么”等帮助功能信息,这些帮助信息都可以轻松设定。

         newItem.setToolTip(toolTipText)
         newItem.setStatusTip(statusTipText)
         newItem.setWhatsThis(whatsThisText)

默认情况下,列表里的项按照它们创建时的顺序来显示,这些列表项也可以按照Qt.SortOrder指定的规则来进行排序,按升序或者降序的排列方式在列表部件中显示。

         listWidget.sortItems(Qt.AscendingOrder)
         listWidget.sortItems(Qt.DescendingOrder)

树形部件QTreeWidget

树形(或层次结构型)的列表项由QTreeWidget和QTreeWidgetItem类提供。树形部件里的每一个项都可以有它自己的子项,同时也可以显示多列信息。树形部件的创建方式和其他部件是一样的:

         treeWidget = QTreeWidget(self)

在把项加到树形部件之前,必须先设定列数。例如,可以定义两列,然后创建一个表头,以便在每一列的顶部提供一个标识:

         treeWidget.setColumnCount(2)
         headers =['Subject', 'Default']
         treeWidget.setHeaderLabels(headers)

为每一列建立标识最容易的方法就是提供一个字符串列表。对于更复杂的表头,则可以构造一个树形项,并按照要求进行设置,然后把它们作为树形部件的表头来使用。

树形部件的顶级项以树形部件作为它们的父部件。它们可以按任意顺序插入,或者在创建每一个项时,通过制定前一个项来确保可以以特定的顺序来列出这些项。

         cities = QTreeWidgetItem(treeWidget)
         cities.setText(0, 'Cities')
         osloItem =QTreeWidgetItem(cities)
         osloItem.setText(0,'Oslo')
         osloItem.setText(1,'Yes')
         plants =QTreeWidgetItem(treeWidget, cities)

树形部件对处理顶层项的方法跟处理其他层次的项的方位稍微不同,树形部件的顶层项可以通过调用树形部件的takeTopLevelItem()函数来进行删除,而其他层次的项则要通过其父项的takeChild()函数来进行删除。顶层项的插入用insertTopLevelItem()函数来完成,其他层次的项则要用父项的insertChild()函数来完成插入。

可以很容易地在树形部件的顶层项与其他层级的项之间移动。在这个过程中,只需要用函数parent()来检测这些项是否是顶层项。比如,不用知道项的具体位置,就可以移除树形部件里的当前项。

         parent =currentItem.parent()
         if parent != None:
                   index = parent.indexOfChild(treeWidget.currentItem())
                   sip.delete(parent.takeChild(index)
         else:
                   index = treeWidget.indexOfTopLevelItem(treeWidget.currentItem())
                   sip.delete(treeWidget.takeTopLevelItem(index)

把项插入到树形部件的某个位置也是使用一样的方式:

         parent=currentItem.parent()
         if parent != None:
                   newItem =QTreeWidgetItem(parent, treeWidget.currentItem())
         else:
                   newItem=QTreeWidgetItem(treeWidget, treeWdiget.currentItem())

表格部件

表格部件和常见的电子表格程序里用到的相似,它由QTableWidget和QTableWidgetItem来创建。它们提供一个带表头的可滚动表格。

在构建表格部件的时候可以指定行数和列数,未定义大小的表格部件也可以在需要的时候再加上行数和列数。

         tableWidget=QTableWidget(12, 3, self)

项可以在添加到表格指定位置之前,在表格外单独创建:

         newItem =QTableWidgetItem(pow(row * (column+1)))
         tableWidget.setItem(row, column, newItem)

通过在表格外创建项,并把它作为表头来使用,就可以添加表格的水平和垂直表头:

         valuseHeaderItem =QTableWidgetItem('Valuse')
         tableWidget.setHorizontalHeaderItem(0, valuseHeaderItem)

注意,表格的行号和列号都是从0开始的。

项视图部件的共有特性

有一些属性是项视图部件类所共有的,它们都可以通过调用每个类的相同接口来使用。

A、隐藏项

有时候需要将项视图部件中的项隐藏和重现,可以通过调用isItemHidden()函数来确认一个项是否被隐藏,使用setItemHidden()函数来隐藏/重现一个项。

B、选择

项的选择方式由部件的选择模式(QAbstractItemView.SelectionMode)来控制。这个属性控制用户是否可以选择一个或多个项,如果是选择多个项,则需要知道选择是否必须在一个连续范围的项。

单向选择:当用户需要在一个部件中选择一个单一的项的时候,默认的SingleSelection模式是最合适的,在这种模式下,当前项和选中项是一样的。

多项选择:使用这种模式,用户可以在不改变当前选择的情况下切换部件中任意项的选择状态,这一点和和复选框的方式很相似。

扩展选择:需要选择许多相邻项的部件(如电子制表)就要使用到扩展选择模式ExtendedSelection。使用这种模式,部件里连续范围的项可以同时用鼠标和键盘进行选择。如果使用修改键,可以创建诸如涉及到部件里跟其它选中的的项不相邻的多个项这样复杂的选择。如果用户在选择一个项时没有使用修改键,那原来的选择就会被清除。

部件中被选中的项可以用 selectedItems()函数来读取,它提供一个可以遍历的相关项的列表。例如,我们可以用下面的代码找出一个选择项列表中所有数值的总和:

         selected =tableWidget.selectedItems()
         total =0
         number=0
         for item in selected:
                   value = float(item.text())
                   total += value
                   number+=1

对于单选模式,当前项是被选中的。而对于多选模式和扩展模式,当前项不一定在选择范围内,它取决于用户选择的方式。

C、搜索

在项视图中快速找到需要的项,无论是对开发人员还是作为一项面向用户的服务,都是很有必要的。上述三种项视图提供了一个通用的findItems()函数,可以实现这个功能。它根据Qt.MatchFlags中的一个值来指定搜索规则按照项的文字来进行搜索。

         found = treeWidget.findItems(itemText, Qt.MatchWildcard)
         for item in found:
                   treeWidget.setItemSelected(item, True)

上面代码运行后得到的结果是,树形部件中的项如果包含搜索字符串中的文字就会被选中,这种方式同样可以应用到列表部件和表格部件。

代码演示

创建文件itemwidgetdemo.py,完整代码如下:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QMainWindow, QSplitter, 
                             QListWidget, QTreeWidget, QTableWidget,
                             QListWidgetItem, QTreeWidgetItem, QTableWidgetItem)
 
class DemoItemWidgets(QMainWindow):
    def __init__(self, parent=None):
        super(DemoItemWidgets, self).__init__(parent)   
        
         # 设置窗口标题
        self.setWindowTitle('实战PyQt5: MV框架 项视图部演示')      
        # 设置窗口大小
        self.resize(640, 360)
      
        self.initUi()
        
    def initUi(self):      
        splitter = QSplitter(Qt.Horizontal)
        
        #列表部件
        listWidget = QListWidget(splitter)
        #方式一,直接添加
        listWidget.addItem('Sycamore')
        #方式二使用listWidget构建一个项
        QListWidgetItem('Chestnut', listWidget)
        #方式三,创建一个项,再插入
        newItem = QListWidgetItem()
        newItem.setText('Mahogany')
        newItem.setToolTip('this is a tool tip')
        newItem.setStatusTip('this is a status tip')
        newItem.setWhatsThis('this is a whats tis text')
        listWidget.insertItem(listWidget.count(), newItem)
        
        #树形部件
        treeWidget = QTreeWidget(splitter)
        #设置列数
        treeWidget.setColumnCount(2)
        #设置头信息
        treeWidget.setHeaderLabels(['Subject','Default'])
        #添加项
        cities = QTreeWidgetItem(treeWidget)
        cities.setText(0, 'Cities')
        osloItem = QTreeWidgetItem(cities)
        osloItem.setText(0, 'Oslo')
        osloItem.setText(1, 'Yes')
        plants = QTreeWidgetItem(treeWidget, cities)
        plants.setText(0, 'Plants')
        
        #表格部件
        tableWidget = QTableWidget(12, 3, splitter)
        #在每个项里填充合适的值
        for row in range(12):
            for column in range(3):
                newItem = QTableWidgetItem(str(pow(row, (column+1))))
                tableWidget.setItem(row, column, newItem)
        #设置第一列的表头信息        
        valuesHeaderItem = QTableWidgetItem('values')
        tableWidget.setHorizontalHeaderItem(0, valuesHeaderItem)
    
        splitter.addWidget(listWidget)
        splitter.addWidget(treeWidget)
        splitter.addWidget(tableWidget)
        self.setCentralWidget(splitter)
    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = DemoItemWidgets()
    window.show()
    sys.exit(app.exec())

运行结果如下图:

本文知识点

  • 了解列表部件QListWidget;
  • 了解树形部件QTreeWidget;
  • 了解表格部件QTableWidget;
  • 上述三个部件的共同点。

喜欢本文内容就关注,收藏,点赞,评论和转发。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表