表格与树

表格与树解决的问题是如何在一个控件中有规律地呈现更多的数据。

QTableView

在通常的情况下,一个应用需要和一批数据(比如数组、列表)进行交互,然后以表格的形式的形式输出这些信息,这是就要用到QTableView类了。在QTableView中可以使用自定义的数据模型来显示内容,通过setModel来绑定数据源。

QTableWidget继承来自QTableVIew,主要的区别在于QTableView可以使用自定义的数据模型来显示内容。而QTableWidget只能使用标准的数据模型,并且其单元数据是通过QTableWidgetItem对象来实现的。

可用的模式:

名称 含义
QStringListModel 存储一组字符串
QStandardItemModel 存储任意层次结构的数据
QDirModel 对文件系统进行封装
QSqlQueryModel 对SQL的查询结果进行封装
QSqlTableModel 对SQL中的表格进行封装
QSqlRetationalTableModel 对带有foreign key的SQL表格进行封装
QSortFilterProxyModel 对模型中的数据进行排序或过滤
# -*- coding: utf-8 -*-

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys

class Table(QWidget):
    def __init__(self, arg=None):
        super(Table,self).__init__(arg)
        self.setWindowTitle("QTableView 表格视图控件的例子")
        self.resize(500,300)
        self.model = QStandardItemModel(4,4)
        self.model.setHorizontalHeaderLabels(['标题1','标题2','标题3','标题4'])
        for row in range(4):
            for column in range(4):
                item = QStandardItem("row %s, column %s"%(row,column))
                self.model.setItem(row, column, item)

        self.tableView = QTableView()
        self.tableView.setModel(self.model)

        dlgLayout = QVBoxLayout()
        dlgLayout.addWidget(self.tableView)
        self.setLayout(dlgLayout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    table = Table()
    table.show()
    sys.exit(app.exec_())

在这里插入图片描述

self.tableView.horizontalHeader().setStretchLastSection(True)
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

将表格填满窗口
在这里插入图片描述

QListView

QListView类用于展示数据,它的子类是QListWidget,QListView是基于模型的,需要程序来建立模型,然后再保存数据。

QListWidget是一个升级版本的QListView,已经建立了一个数据存储模型,直接调用addItem()函数,就可以添加条目(Item)。

常用的方法

  • setModel() 用来设置View所关联的Model,可以使用python原生的list作为数据源model
  • selectItem() 选中Model中的条目
  • isSelected() 判断Model中的条目是否别选中

常用的信号

  • clicked 当点击某个选项的时候,信号被发射
  • doubleClicked 当双击某项时,信号被发射
# -*- coding: utf-8 -*-

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout,QListView, QMessageBox
from PyQt5.QtCore import QStringListModel
import sys

class ListViewDemo(QWidget):
    def __init__(self, parent = None):
        super(ListViewDemo, self).__init__(parent)
        self.setWindowTitle("QListView 例子")
        self.resize(300, 270)
        layout = QVBoxLayout()

        listView = QListView()
        sim = QStringListModel()
        self.qList = ["Item 1","Item 2","Item 3","Item 4"]
        sim.setStringList(self.qList)
        listView.setModel(sim)
        listView.clicked.connect(self.clicked)
        layout.addWidget(listView)
        self.setLayout(layout)

    def clicked(self, qModelIndex):
        QMessageBox.information(self, "ListWidget","你选择了:" + self.qList[qModelIndex.row()])

if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = ListViewDemo()
    win.show()
    sys.exit(app.exec_())

在这里插入图片描述

QListWidget

QListWidget类是一个基于条目的接口,用于从列表中添加或删除条目,

常用的方法

  • addItem() 在列表中添加QListWidgetItem对象或字符
  • addItems() 添加列表中每个条目
  • insertItem() 在指定的索引出插入条目
  • clear() 删除列表中的内容
  • setCurrentItem() 设置当前所选条目
  • sortItem() 按升序重新排列条目

常用的信号

  • currentItemChanged 当列表中的条目发生改变时发射此信号
  • itemClicked 当点击列表中的条目时发射信号
# -*- coding: utf-8 -*-

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class ListWidget(QWidget):
    def __init__(self, parent = None):
        super(ListWidget, self).__init__(parent)
        self.setWindowTitle("QListWidget 例子")
        layout = QVBoxLayout()
        listWidget = QListWidget()
        listWidget.resize(300,120)
        listWidget.addItem("Item 1")
        listWidget.addItem("Item 2")
        listWidget.addItem("Item 3")
        listWidget.addItem("Item 4")
        listWidget.itemClicked.connect(self.clicked)
        layout.addWidget(listWidget)
        self.setLayout(layout)

    def clicked(self, item):
        QMessageBox.information(self, "ListWidget","你选择了:" + item.text())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = ListWidget()
    win.show()
    sys.exit(app.exec_())

在这里插入图片描述

QTableWidget

QTableWidget 是Qt程序中常用的显示数据表格的空间,类似C#中的DataGrid。

常用的方法和枚举类型比较的多,所以可以自行查阅

基本用法

在表格空间中显示的数据是可编辑的。

# -*- coding: utf-8 -*-

import sys
from PyQt5.QtWidgets import QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem

class Table(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("QTabelWidget 例子")
        self.resize(400, 300)
        conLayout = QHBoxLayout()
        tableWidget = QTableWidget()
        tableWidget.setRowCount(4)
        tableWidget.setColumnCount(3)
        conLayout.addWidget(tableWidget)
        tableWidget.setHorizontalHeaderLabels(["姓名","性别","体重(kg)"])
        newItem = QTableWidgetItem("张三")
        tableWidget.setItem(0,0, newItem)

        newItem = QTableWidgetItem("男")
        tableWidget.setItem(0,1,newItem)

        newItem = QTableWidgetItem("160")
        tableWidget.setItem(0,2,newItem)
        self.setLayout(conLayout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = Table()
    example.show()
    sys.exit(app.exec_())

在这里插入图片描述

设置表格头
tableWidget.setHorizontalHeaderLabels()
tableWidget.setVerticalHeaderLabels()

设置表格头伸缩模式

tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

设置为自适应模式

将表格变为禁止模式
tableWidget.setEditTriggers(QAbstractItemView.SelectRows)

设置单元格

设置单元格文本颜色

设置颜色为红色

newItem.setForeground(QBrush(QColor(255, 0, 0)))

在这里插入图片描述

将字体加粗
newItem.setFont(QFont("Times", 12, QFont.Black))

在这里插入图片描述

设置单元格的排序方式
Qt.DescendingOrder
Qt.AscendingOrder
tableWidget.sortItems(2,Qt.DescendingOrder)
设置单元格文本的对齐方式
newItem.setTextAlignment(Qt.AlignRight|Qt.AlignBottom)

在这里插入图片描述

合并单元格效果的效果
tableWidget.setSpan(0,0,3,1)

在这里插入图片描述

设置单元格的大小
tableWidget.setColumnWidth(0,150)
tableWidget.setRowHeight(0,120)

设置第一列的单元格宽度和高度
在这里插入图片描述

在表格中不显示分割线
tableWidget.setShowGrid(False)

在这里插入图片描述

为单元格添加图片
newItem =QTableWidgetItem(QIcon("./images/bao1.png"),"背包")

在这里插入图片描述

支持右键菜单

# -*- coding: utf-8 -*-

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

class Table(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
    def initUI(self):
        self.setWindowTitle("QTableWidget Demo")
        self.resize(500,300)
        conLayout = QHBoxLayout()
        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(5)
        self.tableWidget.setColumnCount(3)
        conLayout.addWidget(self.tableWidget)

        self.tableWidget.setHorizontalHeaderLabels(["姓名","性别","体重"])
        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        newItem = QTableWidgetItem("张三")
        self.tableWidget.setItem(0, 0, newItem)

        newItem = QTableWidgetItem("男")
        self.tableWidget.setItem(0, 1, newItem)
        newItem = QTableWidgetItem("160")
        self.tableWidget.setItem(0, 2, newItem)

        newItem = QTableWidgetItem("李四")
        self.tableWidget.setItem(1, 0, newItem)
        newItem = QTableWidgetItem("女")
        self.tableWidget.setItem(1, 1, newItem)
        newItem = QTableWidgetItem("170")
        self.tableWidget.setItem(1, 2, newItem)
        # 允许右键产生菜单
        self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        # 将右键菜单绑定到槽函数
        self.tableWidget.customContextMenuRequested.connect(self.generateMenu)
        self.setLayout(conLayout)

    def generateMenu(self, pos):
        row_num = -1
        for i in self.tableWidget.selectionModel().selection().indexes():
            row_num = i.row()

        if row_num < 2:
            menu = QMenu()
            item1 = menu.addAction(u"选项一")
            item2 = menu.addAction(u"选项二")
            item3 = menu.addAction(u"选项三")
            action = menu.exec_(self.tableWidget.mapToGlobal(pos))
            if action == item1:
                print("你选了选项一,当前行文字内容是:",self.tableWidget.item(row_num, 0).text(), self.tableWidget.item(row_num,1).text(), self.tableWidget.item(row_num,2).text())
            elif action == item2:
                print("你选了选项二,当前行文字内容是:",self.tableWidget.item(row_num, 0).text(), self.tableWidget.item(row_num,1).text(), self.tableWidget.item(row_num,2).text())
            elif action == item3:
                print("你选了选项三,当前行文字内容是:",self.tableWidget.item(row_num, 0).text(), self.tableWidget.item(row_num,1).text(), self.tableWidget.item(row_num,2).text())
            else:
                return

if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = Table()
    example.show()
    sys.exit(app.exec_())

在这里插入图片描述

你选了选项一,当前行文字内容是: 张三 男 160
你选了选项二,当前行文字内容是: 张三 男 160
你选了选项三,当前行文字内容是: 张三 男 160
你选了选项三,当前行文字内容是: 李四 女 170

QTreeView

QTreeWidget类实现了树形结构

常用的方法

方法 描述
setColumnWidth() 指定列的宽度给设定的值
insertTopLevelItems() 在视图的顶层索引中插入项目列表
expandAll() 展开所有的树形节点
invisibleRootItem 返回树形控件中不可见的根选项
selectedItems() 返回所有固定的非隐藏项目列表

树形结构的实现

# -*- coding: utf-8 -*-

import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *

class Tree(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("TreeWidget 例子")
        self.tree = QTreeWidget()
        self.tree.setColumnCount(2)
        self.tree.setHeaderLabels(['Key','Value'])
        root = QTreeWidgetItem(self.tree)
        root.setText(0,'root')
        root.setIcon(0, QIcon("./images/root.png"))
        # 设置树形控件列的宽度
        self.tree.setColumnWidth(0,160)

        # 设置子结点1
        child1 = QTreeWidgetItem(root)
        child1.setText(0,'Child1')
        child1.setText(1,'ios')
        child1.setIcon(0,QIcon("./images/IOS.png"))
        #设置子结点2
        child2 = QTreeWidgetItem(root)
        child2.setText(0,'child2')
        child2.setText(1,'')
        child2.setIcon(0,QIcon("./images/android.png"))

        # 设置子结点3
        child3 = QTreeWidgetItem(child2)
        child3.setText(0,'child3')
        child3.setText(1,'android')
        child3.setIcon(0,QIcon("./images/music.png"))

        self.tree.addTopLevelItem(root)
        self.tree.expandAll()
        self.setCentralWidget(self.tree)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    tree = Tree()
    tree.show()
    sys.exit(app.exec_())

在这里插入图片描述

系统定制模式

可以使用操作系统提供的定制模式,比如文件系统盘的树列表

# -*- coding: utf-8 -*-

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *

if __name__ == '__main__':
    app = QApplication(sys.argv)
    model = QDirModel()
    tree = QTreeView()
    tree.setModel(model)
    tree.setWindowTitle("QTreeView 例子")
    tree.resize(640,480)
    tree.show()
    sys.exit(app.exec_())

在这里插入图片描述

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐