十、PyQt5 之 数据显示(列表控件、表格控件、树控件)

一、列表控件

1.1、显示列表数据(QListView)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
显示列表数据 (QListView空间)
"""

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


class ListView(QWidget):
    def __init__(self):
        super(ListView, self).__init__()
        self.setWindowTitle("QListView案例")
        self.resize(300, 270)
        layout = QVBoxLayout()

        listview = QListView()
        # 创建一个封装列表的数据源
        listmodel = QStringListModel()
        self.list = ["列表项1", "列表项2", "列表项3"]
        listmodel.setStringList(self.list)
        listview.setModel(listmodel)
        listview.clicked.connect(self.clicked)

        layout.addWidget(listview)
        self.setLayout(layout)

    # 传递过来的 item 为被点击的某一行的对象
    def clicked(self, item):
        # self, 弹框名称, 弹框内容
        QMessageBox.information(self, "QListView", "选择了" + self.list[item.row()])


if __name__ == '__main__':
    app = QApplication(sys.argv)
    table = ListView()
    table.show()
    sys.exit(app.exec_())
复制代码

1.2、扩展的列表控件(QListWidget)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
扩展的列表控件 (QlistWidget)
"""

from PyQt5.QtWidgets import *
import sys


class ListWidget(QMainWindow):
    def __init__(self):
        super(ListWidget, self).__init__()
        self.setWindowTitle("QListView案例")
        self.resize(300, 270)
        self.listwidget = QListWidget()
        self.listwidget.resize(300, 120)
        # 可以直接添加数据,不需要model
        self.listwidget.addItem("item1")
        self.listwidget.addItem("item2")
        self.listwidget.addItem("item3")
        self.listwidget.addItem("item4")
        self.listwidget.addItem("item5")

        self.listwidget.itemClicked.connect(self.clicked)

        # 设置中心控件, 也就是布满整个屏幕,
        self.setCentralWidget(self.listwidget)

    def clicked(self, index):
        # self.listwidget.row() 获得当前被点击的行, self.listwidget.row(index) 获得当前行的元素对象
        QMessageBox.information(self, "QListView", "选择了" + self.listwidget.item(self.listwidget.row(index)).text())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    table = ListWidget()
    table.show()
    sys.exit(app.exec_())
复制代码

二、表格控件

2.1、显示二维表数据(QTableView)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
显示二维表数据 (QTableView)

数据源: QTableView 的数据源 Model
需要创建QTableView实例和一个数据源Model, 然后将两者关联, 类似 MVC 模式
MVC:Model   Viewer   Controller
MVC的目的是将后端的数据和前端页面的耦合度降低
"""

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


class TableView(QWidget):
    def __init__(self):
        super(TableView, self).__init__()
        self.setWindowTitle("QTableView表格视图控件演示")
        self.resize(500, 300)
        # 创建一个 4 行 3 列的 model 表格
        self.model = QStandardItemModel(4, 3)
        self.model.setHorizontalHeaderLabels(["id", "姓名", "年龄"])

        self.tableview = QTableView()
        # 关联 QTableView控件和 Model
        self.tableview.setModel(self.model)

        # 添加数据
        item11 = QStandardItem("10")
        item12 = QStandardItem("WY")
        item13 = QStandardItem("27")
        # 将1行1列数据添加
        self.model.setItem(0, 0, item11)
        self.model.setItem(0, 1, item12)
        self.model.setItem(0, 2, item13)

        # 添加数据
        item31 = QStandardItem("20")
        item32 = QStandardItem("WYY")
        item33 = QStandardItem("28")
        # 将1行1列数据添加
        self.model.setItem(2, 0, item31)
        self.model.setItem(2, 1, item32)
        self.model.setItem(2, 2, item33)


        layout = QVBoxLayout()
        layout.addWidget(self.tableview)
        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    table = TableView()
    table.show()
    sys.exit(app.exec_())
复制代码

2.2、扩展的表格控件(QTableWidget)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
扩展的表格控件(QTableWidget)

QTableView

每一个Cell(单元格)是一个QTableWidgetItem
"""

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


class TableWidgetDemo(QWidget):
    def __init__(self):
        super(TableWidgetDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("QTableWidget演示")
        self.resize(430, 230)

        layout = QHBoxLayout()
        tablewidget = QTableWidget()
        # 设置行数和列数
        tablewidget.setRowCount(4)
        tablewidget.setColumnCount(3)

        layout.addWidget(tablewidget)

        # 添加列的标题
        tablewidget.setHorizontalHeaderLabels(["姓名", "年龄", "工资"])
        # 创建一个QTableWidgetItem对象
        nameItem = QTableWidgetItem("小明")
        # 想姓名添加到底一行一列
        tablewidget.setItem(0, 0, nameItem)

        ageItem = QTableWidgetItem("27")
        tablewidget.setItem(0, 1, ageItem)

        addressItem = QTableWidgetItem("合肥")
        tablewidget.setItem(0, 2, addressItem)

        # 设置禁止编辑
        tablewidget.setEditTriggers(QAbstractItemView.NoEditTriggers)

        # 点击一行选整行
        tablewidget.setSelectionBehavior(QAbstractItemView.SelectRows)

        # 调整行列大小和内容自动匹配
        tablewidget.resizeColumnsToContents()
        tablewidget.resizeRowsToContents()

        # 可以控制表格头行和列显示和隐藏
        tablewidget.horizontalHeader().setVisible(False)
        # tablewidget.verticalHeader().setVisible(False)

        # 默认列的标签时 1,2,3,4, 可以自定义设置
        tablewidget.setVerticalHeaderLabels(["a", "b"])

        # 隐藏表格线
        # tablewidget.setShowGrid(False)

        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = TableWidgetDemo()
    example.show()
    sys.exit(app.exec_())
复制代码

2.3、单元格中放置控件(setCellWidget)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
在单元格中放置控件

setItem:将文本放到单元格中
setCellWidget:将控件放到单元格中
setStyleSheet:设置控件的样式(QSS)
"""
import sys
from PyQt5.QtWidgets import QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem, QAbstractItemView, QComboBox, QPushButton


class PlaceControlInCell(QWidget):
    def __init__(self):
        super(PlaceControlInCell, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("在单元格中放置控件")
        self.resize(430, 300)
        layout = QHBoxLayout()

        tablewidget = QTableWidget()
        tablewidget.setRowCount(4)
        tablewidget.setColumnCount(3)

        layout.addWidget(tablewidget)

        tablewidget.setHorizontalHeaderLabels(["姓名", "性别", "体重/kg"])
        textItem = QTableWidgetItem("小明")
        tablewidget.setItem(0, 0, textItem)

        # 在性别中添加下拉选项控件, 只能从下面两个中选择,不能自己输入
        combox = QComboBox()
        combox.addItem("")
        combox.addItem("")
        # QSS Qt StyleSheet, 相当于CSS, 给combox控件添加样式
        combox.setStyleSheet("QComboBox{margin:3px};")
        tablewidget.setCellWidget(0, 1, combox)

        modifyButton = QPushButton("修改")
        # 设置默认是按下的状态,选中状态
        modifyButton.setDown(True)
        modifyButton.setStyleSheet("QPushButton{margin:3px};")
        tablewidget.setCellWidget(0, 2, modifyButton)

        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = PlaceControlInCell()
    example.show()
    sys.exit(app.exec_())
复制代码

2.4、在表格中搜索单元格的行定位(setSliderPosition)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
在表格中快速定位到特定的行

1. 数据的定位
2. 如果找到了满足条件的单元格,会将定位到单元格所在的行

setSliderPosition(row) 可以通过这个函数直接定位到行
"""

import sys
from PyQt5.QtWidgets import *
from PyQt5 import QtCore
from PyQt5.QtGui import QColor, QBrush


class DataLocation(QWidget):
    def __init__(self):
        super(DataLocation, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("QTableWidget")
        self.resize(600, 800)

        layout = QHBoxLayout()
        tableWidget = QTableWidget()
        tableWidget.setRowCount(40)
        tableWidget.setColumnCount(4)

        layout.addWidget(tableWidget)
        # 给表格添加数据
        for i in range(40):
            for j in range(4):
                itemContent = "(%d, %d)" % (i, j)
                tableWidget.setItem(i, j, QTableWidgetItem(itemContent))

        # 搜索满足条件的Cell
        text = "(13, 1)"
        # findItems(搜索文本, 精确搜索(完全匹配))
        items = tableWidget.findItems(text, QtCore.Qt.MatchExactly)
        if len(items) > 0:
            item = items[0]
            # 找到了设置背景色是绿色
            item.setBackground(QBrush(QColor(0, 255, 0)))
            # 文字的颜色设为红色
            item.setForeground(QBrush(QColor(255, 0, 0)))
            # 获取所在的行
            row = item.row()
            # 定位到指定的行
            tableWidget.verticalScrollBar().setSliderPosition(row)

        # 模糊匹配搜索
        text = "(2"
        items = tableWidget.findItems(text, QtCore.Qt.MatchStartsWith)
        if len(items) > 0:
            for item in items:
                # 找到了设置背景色是绿色
                item.setBackground(QBrush(QColor(0, 255, 0)))
                # 文字的颜色设为红色
                item.setForeground(QBrush(QColor(255, 0, 0)))
                # 获取所在的行
                row = item.row()
                # 定位到指定的行
                tableWidget.verticalScrollBar().setSliderPosition(row)

        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = DataLocation()
    example.show()
    sys.exit(app.exec_())
复制代码

2.5、设置单元格字体和颜色(setBackground、setFont、setForeground)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-


import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem)
from PyQt5.QtGui import QBrush, QColor, QFont


class CellFontAndColor(QWidget):
    def __init__(self):
        super(CellFontAndColor, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("设置单元格字体和颜色")
        self.resize(430, 230)
        layout = QHBoxLayout()
        tableWidget = QTableWidget()
        tableWidget.setRowCount(4)
        tableWidget.setColumnCount(3)
        layout.addWidget(tableWidget)

        tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])

        newItem = QTableWidgetItem("王勇")
        # 设置字体,字号,颜色
        newItem.setFont(QFont('Times', 14, QFont.Black))
        # 设置字体背景
        newItem.setBackground(QBrush(QColor(255, 0, 0)))
        tableWidget.setItem(0, 0, newItem)

        newItem = QTableWidgetItem("")
        newItem.setForeground(QBrush(QColor(255, 255, 0)))
        newItem.setBackground(QBrush(QColor(0, 0, 255)))
        tableWidget.setItem(0, 1, newItem)

        newItem = QTableWidgetItem("72")
        newItem.setFont(QFont('Times', 20, QFont.Black))
        newItem.setForeground(QBrush(QColor(0, 0, 255)))

        tableWidget.setItem(0, 2, newItem)

        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = CellFontAndColor()
    example.show()
    sys.exit(app.exec_())
复制代码

2.6、按表格的某一列排序(sortItems)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""

按列排序
1. 按哪一列排序
2. 升序或者是降序

sortItems(columnIdex, orderType)
"""

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


class ColumnSort(QWidget):
    def __init__(self):
        super(ColumnSort, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("案列排序")
        self.resize(430, 230)

        layout = QVBoxLayout()
        self.tableWideget = QTableWidget()
        self.tableWideget.setRowCount(4)
        self.tableWideget.setColumnCount(3)
        layout.addWidget(self.tableWideget)

        self.tableWideget.setHorizontalHeaderLabels(["姓名", "性别", "体重"])
        newItem = QTableWidgetItem("王勇")
        self.tableWideget.setItem(0, 0, newItem)
        newItem = QTableWidgetItem("")
        self.tableWideget.setItem(0, 1, newItem)
        newItem = QTableWidgetItem("70")
        self.tableWideget.setItem(0, 2, newItem)

        newItem = QTableWidgetItem("WY")
        self.tableWideget.setItem(1, 0, newItem)
        newItem = QTableWidgetItem("")
        self.tableWideget.setItem(1, 1, newItem)
        newItem = QTableWidgetItem("69")
        self.tableWideget.setItem(1, 2, newItem)

        newItem = QTableWidgetItem("WYY")
        self.tableWideget.setItem(2, 0, newItem)
        newItem = QTableWidgetItem("")
        self.tableWideget.setItem(2, 1, newItem)
        newItem = QTableWidgetItem("68")
        self.tableWideget.setItem(2, 2, newItem)

        self.button = QPushButton("排序")
        self.button.clicked.connect(self.order)
        layout.addWidget(self.button)

        # 设为降序排序
        self.orderType = Qt.DescendingOrder

        self.setLayout(layout)

    def order(self):
        if self.orderType == Qt.DescendingOrder:
            self.orderType = Qt.AscendingOrder
        else:
            self.orderType = Qt.DescendingOrder
        # 按照第二列进行排序
        self.tableWideget.sortItems(2, self.orderType)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = ColumnSort()
    example.show()
    sys.exit(app.exec_())
复制代码

2.7、设置单元格的文本对齐方式(setTextAlignment)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
设置单元格文本对齐方式

setTextAlignment

Qt.AlignRight    右对齐
Qt.AlignBottom   下方显示
Qt.AlignCenter   居中对齐
"""

import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem)
from PyQt5.QtCore import Qt


class CellTextAlignment(QWidget):
    def __init__(self):
        super(CellTextAlignment, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("设置单元格文本的对齐方式")
        self.resize(430, 230)
        layout = QHBoxLayout()
        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(4)
        self.tableWidget.setColumnCount(3)
        layout.addWidget(self.tableWidget)

        self.tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])

        newItem = QTableWidgetItem('王勇')
        # 右对齐,底端对齐
        newItem.setTextAlignment(Qt.AlignRight | Qt.AlignBottom)
        self.tableWidget.setItem(0, 0, newItem)

        newItem = QTableWidgetItem('')
        # 居中对齐, 下方对齐
        newItem.setTextAlignment(Qt.AlignCenter | Qt.AlignBottom)
        self.tableWidget.setItem(0, 1, newItem)

        newItem = QTableWidgetItem('70')
        newItem.setTextAlignment(Qt.AlignRight)
        self.tableWidget.setItem(0, 2, newItem)

        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = CellTextAlignment()
    example.show()
    sys.exit(app.exec_())
复制代码

2.8 合并单元格(setSpan)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
合并单元格

# 当前行, 列, 要合并的行个数, 要合并的列个数
setSpan(row, col, row_count, col_count)
"""

import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem)
from PyQt5.QtCore import Qt


class Span(QWidget):
    def __init__(self):
        super(Span, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("设置单元格文本的对齐方式")
        self.resize(430, 230)
        layout = QHBoxLayout()
        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(4)
        self.tableWidget.setColumnCount(3)
        layout.addWidget(self.tableWidget)

        self.tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])

        newItem = QTableWidgetItem('王勇')
        self.tableWidget.setItem(0, 0, newItem)
        self.tableWidget.setSpan(0, 0, 3, 1)

        newItem = QTableWidgetItem('')
        self.tableWidget.setSpan(0, 1, 2, 1)
        self.tableWidget.setItem(0, 1, newItem)

        newItem = QTableWidgetItem('70')
        self.tableWidget.setItem(0, 2, newItem)
        self.tableWidget.setSpan(0, 2, 4, 1)

        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = Span()
    example.show()
    sys.exit(app.exec_())
复制代码

2.9 设置单元格尺寸(setRowHeight、setColumnWidth)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-


import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QBrush, QColor, QFont


class CellFontAndColor(QWidget):
    def __init__(self):
        super(CellFontAndColor, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("设置单元格字体和颜色")
        self.resize(430, 230)
        layout = QHBoxLayout()
        tableWidget = QTableWidget()
        tableWidget.setRowCount(4)
        tableWidget.setColumnCount(3)
        layout.addWidget(tableWidget)

        tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])
        # 设置第一行高度为 80
        tableWidget.setRowHeight(0, 80)
        # 设置第三列宽度
        tableWidget.setColumnWidth(2, 120)
        # 设置第三行高度为 100
        tableWidget.setRowHeight(2, 100)

        newItem = QTableWidgetItem("王勇")
        # 设置字体,字号,颜色
        newItem.setFont(QFont('Times', 30, QFont.Black))
        # 设置字体背景
        newItem.setBackground(QBrush(QColor(255, 0, 0)))
        tableWidget.setItem(0, 0, newItem)

        newItem = QTableWidgetItem("")
        newItem.setForeground(QBrush(QColor(255, 255, 0)))
        newItem.setBackground(QBrush(QColor(0, 0, 255)))
        tableWidget.setItem(0, 1, newItem)

        newItem = QTableWidgetItem("72")
        newItem.setFont(QFont('Times', 60, QFont.Black))
        newItem.setForeground(QBrush(QColor(0, 0, 255)))
        tableWidget.setItem(0, 2, newItem)

        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = CellFontAndColor()
    example.show()
    sys.exit(app.exec_())
复制代码

2.10 在单元格中实现图文混排的效果(QTableWidgetItem(QIcon("image"), "description"))

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
在单元格中实现图文混排的效果
"""

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


class CellImageText(QWidget):
    def __init__(self):
        super(CellImageText, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("在单元格中实现图文混排的效果")
        self.resize(500, 300)
        layout = QHBoxLayout()

        self.tableWideget = QTableWidget()
        self.tableWideget.setRowCount(5)
        self.tableWideget.setColumnCount(4)
        layout.addWidget(self.tableWideget)

        self.tableWideget.setHorizontalHeaderLabels(["姓名", "年龄", "体重", "图片"])

        newItem = QTableWidgetItem("王勇")
        self.tableWideget.setItem(0, 0, newItem)
        newItem = QTableWidgetItem("")
        self.tableWideget.setItem(0, 1, newItem)
        newItem = QTableWidgetItem("70")
        self.tableWideget.setItem(0, 2, newItem)

        newItem = QTableWidgetItem(QIcon("../images/python.png"), "Python")
        self.tableWideget.setItem(0, 3, newItem)
        
        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = CellImageText()
    example.show()
    sys.exit(app.exec_())
复制代码

2.11 改变单元格中图片的尺寸(setIconSize)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
改变单元格中图片的尺寸
setIconSize(QSize(width,height))

"""

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


class CellImageSize(QWidget):
    def __init__(self):
        super(CellImageSize, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("改变单元格中图片的尺寸")
        self.resize(1000, 900)
        layout = QHBoxLayout()

        tablewidget = QTableWidget()
        tablewidget.setIconSize(QSize(300, 200))
        tablewidget.setColumnCount(3)
        tablewidget.setRowCount(5)

        tablewidget.setHorizontalHeaderLabels(["图片1", "图片2", "图片3"])
        # 让列的高度与图片的高度相同
        for i in range(3):
            tablewidget.setRowHeight(i, 300)

        # 让行的高度和图片的高度相同
        for i in range(5):
            tablewidget.setRowHeight(i, 200)

        for k in range(15):
            i = k / 3  #
            j = k % 3  #
            item = QTableWidgetItem()
            item.setIcon(QIcon('./images/bao%d.png' % k))
            tablewidget.setItem(i, j, item)

        layout.addWidget(tablewidget)
        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = CellImageSize()
    example.show()
    sys.exit(app.exec_())
复制代码

2.12 在表格中显示上下文菜单(QMenu.exec_)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
显示列表数据 (QListView空间)

1.  如何弹出菜单
2.  如何在满足条件的情况下弹出菜单

QMenu.exec_
"""

import sys
from PyQt5.QtWidgets import (QMenu, QPushButton, QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem,
                             QHeaderView)
from PyQt5.QtCore import QObject, Qt


class TableWidgetContextMenu(QWidget):

    def __init__(self):
        super(TableWidgetContextMenu, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("在表格中显示上下文菜单")
        self.resize(500, 300)
        layout = QHBoxLayout()
        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(5)
        self.tableWidget.setColumnCount(3)
        layout.addWidget(self.tableWidget)

        self.tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重'])

        newItem = QTableWidgetItem("王勇")
        self.tableWidget.setItem(0, 0, newItem)
        newItem = QTableWidgetItem("")
        self.tableWidget.setItem(0, 1, newItem)
        newItem = QTableWidgetItem("70")
        self.tableWidget.setItem(0, 2, newItem)

        newItem = QTableWidgetItem("WY")
        self.tableWidget.setItem(1, 0, newItem)
        newItem = QTableWidgetItem("")
        self.tableWidget.setItem(1, 1, newItem)
        newItem = QTableWidgetItem("69")
        self.tableWidget.setItem(1, 2, newItem)

        newItem = QTableWidgetItem("WYY")
        self.tableWidget.setItem(2, 0, newItem)
        newItem = QTableWidgetItem("")
        self.tableWidget.setItem(2, 1, newItem)
        newItem = QTableWidgetItem("68")
        self.tableWidget.setItem(2, 2, newItem)

        # 设置允许弹出上下文菜单
        self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tableWidget.customContextMenuRequested.connect(self.generateMenu)

        self.setLayout(layout)

    def generateMenu(self, pos):
        print(pos)
        rowNum = 0
        # 得到被点击的是哪一行,可能是选中多行然后点击了
        for i in self.tableWidget.selectionModel().selection().indexes():
            # 当前选择的行
            rowNum = i.row()
        # 如果选择的行小于2, 弹出上下文菜单
        if rowNum < 2:
            menu = QMenu()
            item1 = menu.addAction("菜单项1")
            item2 = menu.addAction("菜单项2")
            item3 = menu.addAction("菜单项3")
            # 设置被点击后菜单显示位置为相对电脑屏幕界面的位置,而不是窗口的位置,
            # 按照窗口的位置显示的时候会自动编程按照桌面的方式显示,这样显示的位置就跑远了
            screenPos = self.tableWidget.mapToGlobal(pos)
            print(screenPos)

            # 显示菜单, 此时使阻塞状态
            action = menu.exec(screenPos)
            # action = menu.exec(pos) 按照按照相对于窗口的位置在屏幕上显示
            if action == item1:
                print("选择了第1个菜单项", self.tableWidget.item(rowNum, 0).text(), self.tableWidget.item(rowNum, 1).text(),
                      self.tableWidget.item(rowNum, 2).text())
            elif action == item2:
                print("选择了第2个菜单项", self.tableWidget.item(rowNum, 0).text(), self.tableWidget.item(rowNum, 1).text(),
                      self.tableWidget.item(rowNum, 2).text())
            elif action == item3:
                print("选择了第3个菜单项", self.tableWidget.item(rowNum, 0).text(), self.tableWidget.item(rowNum, 1).text(),
                      self.tableWidget.item(rowNum, 2).text())
            else:
                return


if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = TableWidgetContextMenu()
    example.show()
    sys.exit(app.exec_())
复制代码

三、树控件

3.1 树控件的基本用法(QTreeWidget)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon, QBrush, QColor
from PyQt5.QtCore import Qt


class BasicTreeWidget(QMainWindow):
    def __init__(self):
        super(BasicTreeWidget, self).__init__()
        self.setWindowTitle("树控件 QTreeWidget 的基本用法")
        self.tree = QTreeWidget()

        # 设置树控件的列数
        self.tree.setColumnCount(2)

        # 指定列的标签,不指定默认第一列是 1, 第二列是 2
        self.tree.setHeaderLabels(["key", "value"])

        # 为第一列创建根节点
        root = QTreeWidgetItem(self.tree)
        root.setText(0, "根节点“")
        root.setIcon(0, QIcon("./images/root.png"))
        # 设置第一列列宽
        self.tree.setColumnWidth(0, 120)

        # 为根节点创建子节点1
        child1 = QTreeWidgetItem(root)
        # 0 代表第一列的子节点
        child1.setText(0, "子节点")
        child1.setIcon(0, QIcon("./images/bao3.png"))
        # 为子节点添加复选框,设为选中状态
        child1.setCheckState(0, Qt.Checked)
        # child1.setCheckState(0, 0)

        # 为根节点创建子节点2
        child2 = QTreeWidgetItem(root)
        child2.setText(0, "子节点2")
        child2.setIcon(0, QIcon("./images/bao6.png"))

        # 为child2添加一个子节点
        child3 = QTreeWidgetItem(child2)
        child3.setText(0, '子节点2-1')
        # 在对应的第二列添加值,可以用来说明
        child3.setText(1, '新的值')
        child3.setIcon(0, QIcon('./images/music.png'))

        # 设置所有节点处于展开状态
        self.tree.expandAll()

        # 将树控件充满整个屏幕
        self.setCentralWidget(self.tree)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    tree = BasicTreeWidget()
    tree.show()
    sys.exit(app.exec_())
复制代码

3.2 为树控件添加事件

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
为树控件添加相应时间
"""
from PyQt5.QtWidgets import *
import sys


class TreeEvent(QMainWindow):
    def __init__(self, parent=None):
        super(TreeEvent, self).__init__()
        self.setWindowTitle('为树节点添加响应事件')

        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(child2)
        child3.setText(0, "child3")
        child3.setText(1, "3")
        # 为树添加事件
        self.tree.clicked.connect(self.onTreeClicked)

        self.setCentralWidget(self.tree)

    # index 参数可以没有
    def onTreeClicked(self, index):
        item = self.tree.currentItem()
        print(index.row())  # 这个行代表单击节点在父节点中的index位置
        print("key=%s, value=%s" % (item.text(0), item.text(1)))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    tree = TreeEvent()
    tree.show()
    sys.exit(app.exec_())
复制代码

3.3 为树控件添加、修改和删除节点

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-

import sys
from PyQt5.QtWidgets import *


class ModifyTree(QWidget):
    def __init__(self, parent=None):
        super(ModifyTree, self).__init__()
        self.setWindowTitle('添加,、修改、删除节点')

        operatorLayout = QHBoxLayout()
        addBtn = QPushButton('添加节点')
        updateBtn = QPushButton('修改节点')
        deleteBtn = QPushButton('删除节点')

        operatorLayout.addWidget(addBtn)
        operatorLayout.addWidget(updateBtn)
        operatorLayout.addWidget(deleteBtn)

        addBtn.clicked.connect(self.addNode)
        updateBtn.clicked.connect(self.updateNode)
        deleteBtn.clicked.connect(self.deleteNode)

        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(child2)
        child3.setText(0, 'child3')
        child3.setText(1, '3')
        self.tree.clicked.connect(self.onTreeClicked)

        mainLayout = QVBoxLayout(self)
        mainLayout.addLayout(operatorLayout)
        mainLayout.addWidget(self.tree)
        self.setLayout(mainLayout)


    def onTreeClicked(self, index):
        item = self.tree.currentItem()
        print(index.row())
        print('key=%s,value=%s' % (item.text(0), item.text(1)))

    def addNode(self):
        print("添加节点")
        item = self.tree.currentItem()
        print(item)
        node = QTreeWidgetItem(item)
        node.setText(0, "新节点")
        node.setText(1, "新值")

    def updateNode(self):
        print("修改节点")
        item = self.tree.currentItem()
        item.setText(0, '修改节点')
        item.setText(1, '值已经被修改')

    def deleteNode(self):
        print('删除节点')
        # 获取根节点,根节点的父节点不可见,所以单独处理
        root = self.tree.invisibleRootItem()

        # 删除可能是多个节点,节点下面有子节点, 通过节点的父节点删除子节点
        for item in self.tree.selectedItems():
            (item.parent() or root).removeChild(item)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    tree = ModifyTree()
    tree.show()
    sys.exit(app.exec_())
复制代码

3.4 显示当前目录下的树结构(QTreeView、QDirModel)

复制代码
#!/usr/bin/python
# -*- coding:utf-8 -*-


"""
QTreeView 控件与系统定制模式

采用的 Model 模式 进行装载
"""
import sys
from PyQt5.QtWidgets import *

if __name__ == '__main__':
    app = QApplication(sys.argv)

    # 用于显示目录结构的模型
    model = QDirModel()
    tree = QTreeView()
    # 设置 Model
    tree.setModel(model)
    tree.setWindowTitle("TreeView")
    tree.resize(600, 400)
    tree.show()

    sys.exit(app.exec_())
复制代码

 

posted on   软饭攻城狮  阅读(8369)  评论(1编辑  收藏  举报

努力加载评论中...

导航

点击右上角即可分享
微信分享提示