• PyQt5快速开发与实战 5.1 表格与树


    PyQt5快速开发与实战

    5. 第5章 PyQt5 高级界面控件

    5.1 表格与树

    表格与树解决的问题是如何在一个控件中有规律地呈现更多的数据。PyQt提供了两种控件类用于解决该问题,其中一种是表格结构的控件类;另一种是树形结构的控件类。

    5.1.1 QTableView

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

    QTableWidget继承自QTableView,主要区别是 QTableView可以使用自定义的数据模型来显示内容(先要通过setModel来绑定数据源),而 QTableWidget只能使用标准的数据模型,并且其单元格数据是通过QTableWidgetItem对象来实现的。通常使用QTableWidget就能够满足要求。

    QTableView类的继承结构

    在这里插入图片描述

    QTableView控件可以绑定一个模型数据用于更新控件上的内容,可用的模式:

    名称含义
    QStringListModel存储一组字符串
    QStandardItemModel存储任意层次结构的数据
    QDirModel对文件系统进行封装
    QSqlQueryModel对SQL的查询结果集进行封装
    QSqlTableModel对SQL中的表格进行封装
    QSqlRelationalTableModel对带有外键的SQL表格进行封装
    QSortFilterProxyModel对模型中的数据进行排序或过滤

    案例 QTableView的使用

    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 colunm in range(4):
                    item = QStandardItem("row %s , column %s" % (row,colunm))
                    self.model.setItem(row , colunm , item)
    
            self.tableView = QTableView()
            self.tableView.setModel(self.model)
    
            dlgLayout = QVBoxLayout()
            dlgLayout.addWidget(self.tableView)
            self.setLayout(dlgLayout)
    
    if __name__ == '__main__':
        from pyqt5_plugins.examples.exampleqmlitem import QtCore
        QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
        app = QApplication(sys.argv)
        win = Table()
        win.show()
        sys.exit(app.exec_())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    可以看出,表格没有填满窗口,每列可以自由拉动,但是可能会出现滚动条。

    • 把表格填满窗口

      self.tableView.horizontalHeader().setStretchLastSection(True)
      self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
      
      • 1
      • 2

      在这里插入图片描述

    • 添加数据

      self.model.appendRow([
          QStandardItem("row %s , column %s" % (11, 11)),
          QStandardItem("row %s , column %s" % (11, 11)),
          QStandardItem("row %s , column %s" % (11, 11)),
          QStandardItem("row %s , column %s" % (11, 11)),
      ])
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      在这里插入图片描述

    • 删除当前选中的数据

      • 第一种方法

        indexs = self.tableView.selectionModel().selection().indexes()
        if len(indexs) > 0:
            # 取第一行的索引
            index = indexs[0]
            self.model.removeRows(index.row() , 1)
        
        • 1
        • 2
        • 3
        • 4
        • 5
      • 第二种方法

        index = self.tableView.currentIndex()
        print(index.row())
        self.model.removeRow(index.row())
        
        • 1
        • 2
        • 3
    5.1.2 QListView

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

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

    QListView类中的常用方法

    方法描述
    setModel()用来设置View所关联的Model,可以Python原生的list作为数据源Model
    selectedItem()选中Model中的条目
    isSelected()判断Model中的某条目是否被选中

    QListView类中的常用信号

    信号含义
    clicked当单击某项时,信号被反射
    doubleClicked当双击某项时,信号被发射

    案例 QListView的使用

    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()
            slm = QStringListModel()
            self.qlist = ['Item1','Item2','Item3','Item4']
            slm.setStringList(self.qlist)
            listView.setModel(slm)
            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__':
        from pyqt5_plugins.examples.exampleqmlitem import QtCore
        QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
        app = QApplication(sys.argv)
        win = ListViewDemo()
        win.show()
        sys.exit(app.exec_())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    在这里插入图片描述

    5.1.3 QListWidget

    QListWidet类是一个基于条目的接口,用于从列表中添加或删除条目。列表中的每个条目都是一个QListWidgetItem对象。QListWidget可以设置为多重选择。

    QListWidget类中的常用方法

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

    QListWidget类中的常用信号

    信号含义
    currentItemChanged当列表的条目发生改变时发射此信号
    itemClicked当点击列表中的条目时发射此信号

    案例 QListWidget的使用

    import sys
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    
    class ListWidget(QListWidget):
        def clicked(self,item):
            QMessageBox.information(self,"ListWidget","你选择了:" + item.text())
    
    
    if __name__ == '__main__':
        from pyqt5_plugins.examples.exampleqmlitem import QtCore
        QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
        app = QApplication(sys.argv)
        listWidget  = ListWidget()
        listWidget.resize(300 , 120)
        listWidget.addItem("Item 1")
        listWidget.addItem("Item 2")
        listWidget.addItem("Item 3")
        listWidget.addItem("Item 4")
        listWidget.setWindowTitle("QListWidget案例")
        listWidget.itemClicked.connect(listWidget.clicked)
        listWidget.show()
        sys.exit(app.exec_())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

    5.1.4 QTableWidget

    QTableWidget是Qt程序中常用的显示数据表格的空间,类似于C#中的DataGrid。QTableWidget是 QTableView 的子类,它使用标准的数据模型,并且其单元格数据是通过QTableWidgetItem对象来实现的。使用QTableWidget 时就需要QTableWidgetItem,用来表示表格中的一个单元格,整个表格就是用各单元格构建起来的。

    QTableWidget类中的常用方法

    方法描述
    setRowCount(int row)设置QTableWidget表格控件的行数
    setColumnCount(int col)设置QTableWidget表格控件的列数
    setHorizontalHeaderLabels()设置QTableWidget表格控件的水平标签
    setVerticalHeaderLabelsO设置QTableWidget表格控件的垂直标签
    setItem(int, int, QTableWidgetItem)在 QTableWidget表格控件的每个选项的单元空间里添加控件
    horizontalHeader()获得QTableWidget表格控件的表格头,以便执行隐藏
    rowCount()获得QTableWidget表格控件的行数
    columnCount()获得QTableWidget表格控件的列数
    setEditTriggers(EditTriggers triggers)设置表格是否可编辑。设置编辑规则的枚举值
    setSelectionBehavior设置表格的选择行为
    setTextAlignment()设置单元格内文字的对齐方式
    setSpan(int row, int column, int rowSpanCount,int columnSpanCount)合并单元格,要改变单元格的第row行第column列,要合并rowSpanCount行数和columnSpanCount列数。row:要改变的单元格行数;
    column:要改变的单元格列数;rowSpanCount:需要合并的行数 ;columnSpanCount:需要合并的列数
    setShowGrid()在默认情况下,表格的显示是有网格线的。True:显示网格线;False:不显示网格线
    setColumnWidth(int column, int width)设置单元格行的宽度
    setRowHeight(int row, int height)设置单元格行的高度

    编辑规则的枚举值类型

    选项描述
    QAbstractItemView.NoEditTriggers0No0不能对表格内容进行修改
    QAbstractItemView.CurrentChanged1Editing1任何时候都能对单元格进行修改
    QAbstractItemView.DoubleClicked2Editing2双击单元格
    QAbstractItem View.SelectedClicked4Editing4单击已选中的内容
    QAbstractItemView.EditKeyPressed8Editing8当修改键被按下时修改单元格
    QAbstractltemVew.AnyKeyPressed16Editing16按任意键修改单元格
    QAbstractltemView.AllEditTriggers31Editing31包括以上所有条件

    表格的选择行为的枚举值类型

    选项描述
    QAbstractItemView.SelectItems0Selecting0选中单个单元格
    QAbstractItemView.SelectRows1Selecting1选中一行
    QAbstractItem View.SelectColumns2Selecting2选中一列

    单元格文本的水平对齐方式

    选项描述
    Qt.AlignLeft将单元格的内容沿单元格的左边缘对齐
    Qt.AlignRight将单元格的内容沿单元格的右边缘对齐
    Qt.AlignHCenter在可用空间上,居中显示在水平方向上
    Qt.AlignJustify将文本在可用空间中对齐,默认是从左到右的

    单元格文本的垂直对齐方式

    选项描述
    Qt.AlignTop与顶部对齐
    Qt.AlignBottom与底部对齐
    Qt.AlignVCenter在可用空间中,居中显示在垂直方向上
    Qt.AlignBaseline与基线对齐

    如果要设置水平和垂直对齐方式,比如在表格空间内上下、左右居中对齐,那么只要使用Qt.AlignHCenter 和 Qt.AlignVCenter即可。

    1. 基本用法

      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("QTableWidget案例")
              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("70")
              tableWidget.setItem(0 , 2, newItem)
      
              self.setLayout(conLayout)
      
      if __name__ == '__main__':
          from pyqt5_plugins.examples.exampleqmlitem import QtCore
          QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
          app = QApplication(sys.argv)
          win = Table()
          win.show()
          sys.exit(app.exec_())
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34

      在这里插入图片描述

      ① 在默认情况下, 表格里的字符串是可以更改的

      ② 生成表格,要先初始化行号和列号,再设置表格的表头标签,否则没有效果

      • 设置表格头为伸缩模式:

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

        在这里插入图片描述

      • 将表格变为禁止编辑

        tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) 
        
        • 1

        在这里插入图片描述

      • 设置表格整行选中

        【表格默认选中是某个单个单元格】

        tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        
        • 1

        在这里插入图片描述

      • 将行和列的宽度、高度设置为与所显示内容的宽度、高度相匹配

        这里先把伸缩模式关闭,不然没效果

        tableWidget.resizeColumnsToContents()
        tableWidget.resizeRowsToContents()
        
        • 1
        • 2

        在这里插入图片描述

      • 表格头的显示与隐藏

        # 垂直方向
        tableWidget.verticalHeader().setVisible(False)
        #  水平方向
        tableWidget.horizontalHeader().setVisible(False)
        
        • 1
        • 2
        • 3
        • 4

        在这里插入图片描述

      • 在单元格中放置控件

        QTableWidget不仅允许往单元格中放置文字,还允许放置控件,通过TableWidget.setItem()来添加PyQt的基本控件。

        conBox =  QComboBox()
        conBox.addItem("男")
        conBox.addItem("女")
        conBox.setStyleSheet("QComboBox{margin:3px};")
        tableWidget.setCellWidget(0,1,conBox)
        
        searchBtn = QPushButton("修改")
        searchBtn.setDown(True)
        searchBtn.setStyleSheet("QPushButton{margin:3px};")
        tableWidget.setCellWidget(0,2,searchBtn)
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10

        在这里插入图片描述

      • 从表格中快速定位到指定行

        当tableWidget表格的行数很多时,可以通过输入行号进行直接定位并显示,比如输入10,就直接显示第10行。

        import sys
        from PyQt5.QtWidgets import *
        from PyQt5 import QtCore
        from PyQt5.QtGui import QColor, QBrush
        
        
        class Table(QWidget):
            def __init__(self):
                super().__init__()
                self.initUI()
        
            def initUI(self):
                self.setWindowTitle("QTableWidget 例子")
                self.resize(600, 800);
                conLayout = QHBoxLayout()
                tableWidget = QTableWidget()
                tableWidget.setRowCount(30)
                tableWidget.setColumnCount(4)
                conLayout.addWidget(tableWidget)
        
                for i in range(30):
                    for j in range(4):
                        itemContent = '(%d,%d)' % (i, j)
                        tableWidget.setItem(i, j, QTableWidgetItem(itemContent))
                self.setLayout(conLayout)
        
                # 遍历表查找对应的item
                text = "(10,1)"
                items = tableWidget.findItems(text, QtCore.Qt.MatchExactly)
                item = items[0]
                # 选中单元格
                # item.setSelected( True)
                # 设置单元格的背景颜色为红色
                item.setForeground(QBrush(QColor(255, 0, 0)))
        
                row = item.row()
                # 滚轮定位过去,快速定位到第17行
                tableWidget.verticalScrollBar().setSliderPosition(row)
        
        if __name__ == '__main__':
            from pyqt5_plugins.examples.exampleqmlitem import QtCore
            QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
            app = QApplication(sys.argv)
            win = Table()
            win.show()
            sys.exit(app.exec_())
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
        • 37
        • 38
        • 39
        • 40
        • 41
        • 42
        • 43
        • 44
        • 45
        • 46

        在这里插入图片描述

    2. 设置单元格

      • 设置单元格文本颜色

        import sys
        from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem)
        from PyQt5.QtGui import QBrush, QColor, QFont
        
        
        class Table(QWidget):
            def __init__(self):
                super().__init__()
                self.initUI()
        
            def initUI(self):
                self.setWindowTitle("QTableWidget 例子")
                self.resize(430, 230);
                conLayout = QHBoxLayout()
                tableWidget = QTableWidget()
                tableWidget.setRowCount(4)
                tableWidget.setColumnCount(3)
                conLayout.addWidget(tableWidget)
        
                tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])
        
                newItem = QTableWidgetItem("张三")
                newItem.setForeground(QBrush(QColor(255, 0, 0)))
                tableWidget.setItem(0, 0, newItem)
        
                newItem = QTableWidgetItem("男")
                newItem.setForeground(QBrush(QColor(255, 0, 0)))
                tableWidget.setItem(0, 1, newItem)
        
                newItem = QTableWidgetItem("70")
                newItem.setForeground(QBrush(QColor(255, 0, 0)))
                tableWidget.setItem(0, 2, newItem)
        
                self.setLayout(conLayout)
        
        if __name__ == '__main__':
            from pyqt5_plugins.examples.exampleqmlitem import QtCore
            QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
            app = QApplication(sys.argv)
            win = Table()
            win.show()
            sys.exit(app.exec_())
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
        • 37
        • 38
        • 39
        • 40
        • 41
        • 42

        在这里插入图片描述

      • 将字体加粗

        newItem.setFont(QFont("Times",12,QFont.Black))
        
        • 1

        在这里插入图片描述

      • 设置单元格的排序方式

        ## DescendingOrder 降序
        ## AscendingOrder 升序
        # tableWidget.sortItems(2,Qt.DescendingOrder)
        tableWidget.sortItems(2, Qt.AscendingOrder)
        
        • 1
        • 2
        • 3
        • 4

        在这里插入图片描述

      • 设置单元格文本的对齐方式

        使用QTableWidgetItem.setTextAlignment(int)函数设置单元格文本的对齐方式。

        newItem.setTextAlignment(Qt.AlignRight | Qt.AlignBottom)
        
        • 1

        在这里插入图片描述

      • 合并单元格效果的实现

        tableWidget.setSpan(0 , 0 , 3 , 1)
        
        • 1

        在这里插入图片描述

      • 设置单元格的大小

        # 将第一列的单元格宽度设置为150
        tableWidget.setColumnWidth(0 , 150)
        # 将第一行的单元格高度设置为120
        tableWidget.setRowHeight(0 , 120)
        
        • 1
        • 2
        • 3
        • 4

        在这里插入图片描述

      • 在表格中不显示分割线

        默认显示

        tableWidget.setShowGrid(False)
        
        • 1

        在这里插入图片描述

      • 为单元格添加图片

        进行这步前,需要调整一下表格的布局

        newItem = QTableWidgetItem(QIcon("images/bao1.png"), "背包")
        tableWidget.setItem(0, 3, newItem)
        
        • 1
        • 2

        在这里插入图片描述

      • 改变单元格中显示的图片大小

        import sys
        from PyQt5.QtWidgets import *
        from PyQt5.QtGui import *
        from PyQt5.QtCore import *
        
        
        class Table(QWidget):
            def __init__(self):
                super().__init__()
                self.initUI()
        
            def initUI(self):
                self.setWindowTitle("QTableWidget 例子")
                self.resize(1000, 900);
                conLayout = QHBoxLayout()
        
                table = QTableWidget()
                table.setColumnCount(3)
                table.setRowCount(5)
        
                table.setHorizontalHeaderLabels(['图片1', '图片2', '图片3'])
        
                table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        
                table.setIconSize(QSize(300, 200));
        
                for i in range(3):  # 让列宽和图片相同
                    table.setColumnWidth(i, 300)
                for i in range(5):  # 让行高和图片相同
                    table.setRowHeight(i, 200)
        
                for k in range(15):  # 27 examples of DDA
                    i = k / 3
                    j = k % 3
                    item = QTableWidgetItem()
                    item.setFlags(Qt.ItemIsEnabled)  # 用户点击时表格时,图片被选中
                    icon = QIcon(r'images/bao%d.png' % k)
                    item.setIcon(QIcon(icon))
        
                    print('e/icons/%d.png i=%d  j=%d' % (k, i, j))
                    table.setItem(i, j, item)
        
                conLayout.addWidget(table)
                self.setLayout(conLayout)
        
        if __name__ == '__main__':
            # from pyqt5_plugins.examples.exampleqmlitem import QtCore
            # QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
            app = QApplication(sys.argv)
            win = Table()
            win.show()
            sys.exit(app.exec_())
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
        • 37
        • 38
        • 39
        • 40
        • 41
        • 42
        • 43
        • 44
        • 45
        • 46
        • 47
        • 48
        • 49
        • 50
        • 51
        • 52

        在这里插入图片描述

      • 获得单元格的内容

        通过实现 itemClicked (QTableWidgetIltem *)信号的槽函数,可以获得所点击的单元格的引用,进而获得其中的内容。

        在这里插入图片描述

    3. 支持右键菜单

      import sys
      from PyQt5.QtWidgets import (QMenu, QPushButton, QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem,
                                   QHeaderView)
      from PyQt5.QtCore import QObject, Qt
      
      
      class Table(QWidget):
      
          def __init__(self):
              super().__init__()
              self.initUI()
      
          def initUI(self):
              self.setWindowTitle("QTableWidget 例子")
              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("80")
              self.tableWidget.setItem(0, 2, newItem)
              # 表格中第二行记录
              newItem = QTableWidgetItem("李四")
              self.tableWidget.setItem(1, 0, newItem)
      
              newItem = QTableWidgetItem("女")
              self.tableWidget.setItem(1, 1, newItem)
      
              newItem = QTableWidgetItem("75")
              self.tableWidget.setItem(1, 2, newItem)
      
              self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu)  ######允许右键产生子菜单
              self.tableWidget.customContextMenuRequested.connect(self.generateMenu)  ####右键菜单
              self.setLayout(conLayout)
      
          def generateMenu(self, pos):
              # rint( 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__':
          from pyqt5_plugins.examples.exampleqmlitem import QtCore
          QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
          app = QApplication(sys.argv)
          win = Table()
          win.show()
          sys.exit(app.exec_())
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79

      在这里插入图片描述

    5.1.5 QTreeView

    QTreeWidget类实现了树形结构。

    QTreeWidget类的继承结构:

    QWidget → QFrame → QAbstractScrollArea → QAbstractItemView → QAbstractScrollArea → QAbstractItemView → QTreeView → QTreeWidget

    QTreeWidget类中的常用方法

    方法描述
    setColumnWidth(int column , int width)将指定列的宽度设置为给定的值;Column,指定的列;Width,指定列的宽度
    insertTopLevelItems()在视图的顶层索引中插入项目列表
    expandAll()展开所有的树形节点
    invisibelRootItem()返回树形控件中不可见的根选项(Root Item)
    selectedItems()返回所有选定的非隐藏项目的列表

    QTreeWidgetItem类中的常用方法

    方法描述
    addChild()将子项追加到子列表中
    setText()设置显示的节点文本
    Text()返回显示的节点文本
    setCheckState(column , state)设置指定列的选中状态:Qt.Checked,节点选中;Qt.Unchecked,节点未选中
    setIcon在指定的列中显示图标
    1. 树形结构的实现

      树形结构是通过QTreeWidget和 QTreeWidgetItem类实现的,其中QTreeWidgetltem类实现了节点的添加。

      import sys
      from PyQt5.QtWidgets import *
      from PyQt5.QtGui import QIcon, QBrush, QColor
      from PyQt5.QtCore import Qt
      
      
      class TreeWidgetDemo(QMainWindow):
          def __init__(self, parent=None):
              super(TreeWidgetDemo, self).__init__(parent)
              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)
      
              ### 设置节点的背景颜色
              # brush_red = QBrush(Qt.red)
              # root.setBackground(0, brush_red)
              # brush_green = QBrush(Qt.green)
              # root.setBackground(1, brush_green)
      
              # 设置子节点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__':
          from pyqt5_plugins.examples.exampleqmlitem import QtCore
          QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
          app = QApplication(sys.argv)
          win = TreeWidgetDemo()
          win.show()
          sys.exit(app.exec_())
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60

      在这里插入图片描述

      • 设置节点状态

        可以使用QTreeWidgetItem的setCheckState()函数设置节点是否为选中状态。

        child1.setCheckState(0, Qt.Checked)
        
        • 1

        在这里插入图片描述

      • 设置节点的背景颜色

        可以使用QBrush类来设置节点的背景颜色。

        brush_red = QBrush(Qt.red)
        root.setBackground(0,brush_red)
        brush_green = QBrush(Qt.green)
        root.setBackground(1,brush_green)
        
        • 1
        • 2
        • 3
        • 4

        在这里插入图片描述

    2. 给节点添加响应事件

    from PyQt5.QtWidgets import *
    import sys
    
    
    class TreeWidgetDemo(QMainWindow):
        def __init__(self, parent=None):
            super(TreeWidgetDemo, self).__init__(parent)
            self.setWindowTitle('TreeWidget 例子')
            self.tree = QTreeWidget()
            # 设置列数
            self.tree.setColumnCount(2)
            # 设置头的标题
            self.tree.setHeaderLabels(['Key', 'Value'])
            root = QTreeWidgetItem(self.tree)
            root.setText(0, 'root')
            root.setText(1, '0')
    
            child1 = QTreeWidgetItem(root)
            child1.setText(0, 'child1')
            child1.setText(1, '1')
    
            child2 = QTreeWidgetItem(root)
            child2.setText(0, 'child2')
            child2.setText(1, '2')
    
            child3 = QTreeWidgetItem(root)
            child3.setText(0, 'child3')
            child3.setText(1, '3')
    
            child4 = QTreeWidgetItem(child3)
            child4.setText(0, 'child4')
            child4.setText(1, '4')
    
            child5 = QTreeWidgetItem(child3)
            child5.setText(0, 'child5')
            child5.setText(1, '5')
    
            self.tree.addTopLevelItem(root)
            self.tree.clicked.connect(self.onTreeClicked)
    
            self.setCentralWidget(self.tree)
    
        def onTreeClicked(self, qmodelindex):
            item = self.tree.currentItem()
            print("key=%s ,value=%s" % (item.text(0), item.text(1)))
    
    if __name__ == '__main__':
        from pyqt5_plugins.examples.exampleqmlitem import QtCore
        QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
        app = QApplication(sys.argv)
        win = TreeWidgetDemo()
        win.show()
        sys.exit(app.exec_())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    在这里插入图片描述

    1. 系统定制模式

    QTreeWidgetItem类的节点是一个个添加的,这样做有时很不方便,特别是当窗口中产生比较复杂的树形结构时,一般都是通过OTreeView类来实现的,而不是QTreeWidget类。OTreeView类与 QTreeWidget类最大的区别就是,QTreeView类可以使用操作系统提供的定制模式,比如文件系统盘的树列表。

    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import *
    
    if __name__ == '__main__':
        from pyqt5_plugins.examples.exampleqmlitem import QtCore
        QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
    
        app = QApplication(sys.argv)
        model = QDirModel()
        tree = QTreeView()
    
        tree.setModel(model)
        tree.setWindowTitle("QTreeView案例")
        tree.resize(640,480)
        tree.show()
        sys.exit(app.exec_())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

  • 相关阅读:
    关于利用talib.macd函数计算macd指标与同花顺不一致的问题
    如何进行跨平台开发和移植性处理?
    PhalAPI学习笔记 ——— 第一章自定义HelloWorld接口
    obsidian和zotero联动
    七天入门node.js(05)
    Python史上最全种类数据库操作方法,你能想到的数据库类型都在里面!甚至还有云数据库!
    文本搜索小程序
    使用idea创建多模块Maven项目(模块间的继承与依赖)
    步入式老化房采集模拟量电流电压
    第7章 - 多无人机系统的协同控制 --> 无人机模型分析
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/126032821