119-Model/View-表格视图QTableView

表格视图QTableView

QTableView实现了一个列表视图,用于显示模型中的项目(item)。

QTableView 在早期基于QTable类提供视图现在基于Qt的模型/视图框架提供更灵活的视图。QTableView是模型/视图类之一,也是 Qt 中模型/视图框架的一部分。

QTableView实现了QAbstractItemView定义的接口,以允许它显示从OAbstractItemModel派生的模型提供的数据。QTableView 一般和QStandardItemModel 结合使用。

OStandardItemModel提供了一种基于项目(item)的方法来处理模型。

QStandardItemModel中的item 由QStandardItem 提供。这种方式和 QTableWidget 一样,基本元素都是item,QTableWidget 的item 由QTableWidgetItem 提供。

QTableView和QTableWidget 的使用非常相似,所以两者有非常多的共同点,但也有不同之处。

表格视图控件QTableView 可以用多行多列的单元格来显示标准数据模型,也可显示其他类型的数据模型

用QTableView创建表格视图控件的方法如下所示,其中parent是继承自QWidget的窗口或容器控件。

from PySide6.QtWidgets import QTableView

QTableView(parent: Union[PySide6.QtWidgets.QWidget,NoneType]= None)-> None

表格视图控件QTableView的常用方法

方法总览

表格视图控件QTableView 以二维表格的形式显示数据模型中的数据,其常用方法如表所示,主要方法介绍如下。

  • 用setModel(QAbstractItemModel)方法设置表格视图控件的数据模型
  • 用setrootIndex(QModelIndex)方法设置根目录(不可见)的数据索引,
  • 用setSelectionModel(QItemSelectionModel)方法设置选择模型
  • 用setColumnWidth(int,int)方法和 setRowHeight(int,int)方法设置列的宽度和行的高度,
    • 用columnWidth(int)方法和 rowHeight(int)方法获取列的宽度和行的高度。
  • 表格视图控件有坐标系
    • 用columnAt(x;int)方法获取坐标位置处的列号
    • 用rowAt(y:int)方法获取y坐标位置处的行号,
    • 用columnViewportPasition(column;int)方法获取指定列的x坐标值,
    • 用rowViewportPosition(row;int)方法获取指定行的坐标值。
  • 行和列可以根据内容调整高度和宽度
    • 用resizeColumnToContents(column; int)方法和resizeColumnsToContents()方法自动调整列的宽度,
    • 用resizeRowToContents(row:int)方法和 resizeRowsToContents()方法自动调整行的高度。
  • 在表格的左上角有个按钮,单击该按钮可以选中所有数据,
    • 用setCornerButtonEnabled(bool)方法设置是否激活该按钮。
    • 用setShowGrid(bool)方法设置是否显示表格线条,
  • 用setGridStyle(Qt.PenStyle)方法可以设置表格线条的样式,其中参数 Qt PenStyle 可取:
    • Qt.NoPen(没有表格线条)
    • Qt.SolidLine,
    • Qt.DashLine、
    • Qt.DotLine,
    • Qt.DashDotLine,
    • Qt.DashDotDotLine
    • Qt.CustomDashLine(用setDashPattern()方法自定义)
QTableView的方法及参数类型返回值的类型说明
setModel(QAbstractItemModel)None设置关联的数据模型
setrootIndex(QModelIndex)None设置根目录的数据索引
setSelectionModel(QItemSelectionModel)None设置选择模型
selectionModel()QItemSelectionModel获取选择模型
setSelection(rect:QRect,command: QItemSelectionModel.SelectionFlags)None选择指定范围内的数据项
columnAt(x:int)int获取×坐标位置处的列号
rowAt(y: int)int获取y坐标位置处的行号
columnViewportPosition(column:int)int获取指定列的×坐标值
rowViewportPosition(row:int)int获取指定行的y坐标值
indexAt(QPoint)QModelIndex获取指定位置的数据索引
selectedIndexes()List[int]获取选中的项的索引列表
resizeColumnToContents(column:int)None自动调整指定列的宽度
resizeColumnsToContents()None根据内容自动调整列的宽度
resizeRowToContents(row:int)None自动调整指定行的高度
resizeRowsToContents()None根据内容自动调整行的高度
scrollTo(QModelIndex)None滚动表格使指定内容可见
selectColumn(column:int)None选择列
selectRow(row:int)None选择行
setColumnHidden(column:int,bool)None设置是否隐藏列
hideColumn(column:int)None隐藏列
setRowHidden(row:int,bool)None设置是否隐藏行
hideRow(row:int)None隐藏行
showColumn(column:int)None显示列
showRow(row:int)None显示行
isColumnHidden(column:int)bool获取指定的列是否隐藏
isRowHidden(row:int)bool获取指定的行是否隐藏
islndexHidden(QModelIndex)bool获取索引对应的单元格是否隐藏
setShowGrid(bool)None设置是否显示表格线条
showGrid()bo01获取表格线条是否已显示
setGridStyle(Qt.PenStyle)None设置表格线的样式
setColumnWidth(column:int,width:int)None设置列的宽度
columnWidth(column:int)int获取列的宽度
setRowHeight(row: int,height: int)None设置行的高度
rowHeight(row:int)int获取行的高度
setCornerButtonEnabled(bool)None设置是否激活右下角按钮
isCornerButtonEnabled()bool获取右下角按钮是否激活
setVerticalHeader(QHeaderView)None设置竖直表头
verticalHeader()QHeaderView获取竖直表头
setHorizontalHeader(QHeaderView)None设置水平表头
horizontalHeader()QHeaderView获取水平表头
setSpan(row:int,column: int,rowSpan: intcolumnSpan:int)None设置单元格的行跨度和列跨度
columnSpan(row:int,column:int)int获取单元格的列跨度
rowSpan(row:int,column:int)int获取单元格的行跨度
clearSpans()None清除跨度
setWordWrap(bool)None设置字可以写到多行上
setSortingEnabled(bool)None设置是否可以排序
isSortingEnabled()bool获取是否可以排序
sortByColumn(int,Qt.SortOrder)None按列进行排序
scrollContentsBy(dx: int,dy:int)None把表格移动指定的距离
scrollTo(index: QModelIndex,hint = QAbstractItemView.EnsureVisible)None使指定的项可见
setAlternatingRowColors(enable: bool)None设置行的颜色交替变化
绑定模型和初始化数据

QTableView 通过 setModel()函数添加模型,如下所示

self.tableView = QTableView()
self.model = QStandardItemModel(5,4)
self.tableView,setModel(self.model)

除了QStandardItemModel,QTableView 还经常和 QItemSelectionModel一起使用,用来支持选择功能:

self.selectModel = QItemSelectionModel()
self.tableView.setSelectionModel(self.selectModel)

可以把 QTableView、QStandardItemModel 和QItemSelectionModel 的合体当作一个QTableWidget。

与QTableWidget 不同,QTableView 的很大一部分功能(如数据管理)要依赖QStandardItemModel,所以要把先了解QStandardItemModel。

导航

导航功能继承自 QAbstractItemView,QAbstractItemView 提供了一个标准接口,用于通过信号/槽机制与模型进行互动,使子类能够随着模型的更改而保持最新状态QAbstractItemView 为键盘和鼠标导航、视口滚动、项目编辑和选择提供标准支持。

键盘导航实现的功能如表所示。

按键功 能
Arrow keys更改当前项目并选择它
Ctrl+Arrow keys更改当前项目但不选择它
Shift+Arow keys更改当前项目并选择它,先前选择的项目不会取消选择
Ctrl+Space切换当前项目的选择
Tab/Backtab将当前项目更改为下一个/上一个项目
Home/End选择模型中的第一个/最后一个项目
Page up/Page down按视图中的可见行数向上/向下滚动显示的行
CtrI+A选择模型中的所有项目
基于行/列读取
  • 使用 rowHeight(row:int)可以获取每行的高度,
  • 使用 columnWidth(col;int)可以获取每列的宽度。
  • 使用 hideRow(row:int)、hideColumn(col;int)、showRow(row;int)和 showColumn(col;int)可以隐藏和显示行/列。
  • 使用 selectRow(row:int)和 selectColumn(col:int)可以选择行/列。
  • 使用 showGrid0函数的结果可以判断是否显示网格。
自定义小部件

表视图中显示的项目(item)默认使用标准委托进行染和编辑。但是有些任务需要在表格中插入自定义小部件

使用 setIndexWidget0函数可以解决这个问题(使用setindexWidget()函数可以查找自定义小部件,如果不存在则返回空):

setIndexWidget(self,
               index: PySide6.QtCore.QModelIndex,
               widget:PySide6.Qtwidgets.Qwidget)-> None

需要注意的是,这里传递的 index 是一个模型的索引,使用方式如下:

#自定义控件
self.tableview.setIndexWidget(self.model.index(4,3),QLineEdit('自定义控件-1'*3))
self.tableview.setIndexWidget(self.model.index(4,2),QSpinBox())

这是视图方法,所以尽管自定义小部件的数据发生了变化,但是模型中的数据不会改变,也就是说,基于模型的其他视图的数据也不会改变。

坐标系

有时需要对行/列的索引和小部件坐标进行转换:

  • rowAt(y:int)返回视图中y坐标对应的行

  • rowViewportPosition(row:int)返回行数row对应的y坐标。

  • 对于列,可以使用columnAt()函数和columnViewportPosition()函数获取x坐标和列索引之间的关系。示例如下:

    row = self.tableView.currentIndex().row()
    rowPositon = self.tableView.rowViewportPosition(row)
    rowAt = self.tableView.rowAt(rowPositon)
    
创建表头(标题)

使用verticalHeader()函数可以获取表格的垂直表头,使用horizontalHeader()函数可以获取表格的水平表头,两者都返回 QHeaderView。

QHeaderView 也是 QAbstractItemView的子类,并且为 QTableWidget(QTableView)提供了表头视图。

如果不想看到行或列则可以使用 hide())函数隐藏。

创建表头最简单的方法是使用 setHorizontalHeaderLabels()函数和 setVerticalHeaderLabels()函数,两者都将字符串列表作为参数,为表格的列和行提供简单的文本标题。示例如下:

rowCount = self.model.rowCount()
self.model,setVerticalHeaderlabels([f'row(ij'for i in range(rowCount)1)

当然,也可以基于 QStandardItem 创建更复杂的表头标题。示例如下

cusHeaderItem = QStandardItem("cusHeader")
cusHeaderItem.setIcon(QIcon("images/android.png"))
cusHeaderItem,setTextAlignment(Qt.AlignVCenter)
cusHeaderItem,setForeground(QBrush(QColor(255,0,0)))
self.model.setHorizontalHeaderItem(2,cusHeaderItem)
调整行/列的大小

可以通过QHeaderView 来调整表格中的行/列行为,每个QHeaderView 包含一个方向orientation0和N个 section(通过 count0函数获取N),section 表示行/列的一个基本单元OHeaderView 的很多函数都和 section 相关。

可以使用 moveSection(from: int,to: int)和resizeSection(logicalIndex: int,size: int)移动和调整行/列的大小。

QHeaderView 提供了一些函数用来控制标题移动、单击、大小调节行为:

  • 使用 setSectionsMovable(ovable:bool)可以开启移动行为,使用 setSectionsClickable(clickable: bool)使其可以单击,

  • 使用setSectionResizeMode0函数可以设置大小调整行为。

  • 与之相应的,以上几种行为会触发如下槽函数:移动触发 sectionMoved(),调整大小触发 sectionResized(),鼠标单击触发 sectionClicked()及 sectionHandleDoubleClicked0。

  • 此外,当添加或删除 section 时,触发 sectionCountChanged()

setSectionResizeMode支持两种调节方式,即全局设置和局部设置,参数如下:

setSectionResizeMode(self,logicalIndex: int,mode:QHeaderView.ResizeMode)->None
setSectionResizeMode(self,mode: OHeaderView.ResizeMode)-> None

QHeaderViewResizeMode 支持的参数如表所示

参 数描述
QHeaderView.Interactive0用户可以调整该部分的大小。
也可以使用 resizeSectionO函数以编程方 式调整节的大小,节的大小默认为defaultSectionSize
QHeaderView.Fixed2用户无法调整该部分的大小。
该部分只能使用 resizeSectionO函数以编 程方式调整节的大小,节的大小默认为defaultSectionSize
QHeaderView.Stretch1QHeaderView 将自动调整该部分的大小以填充可用空间,用户以编程方 式无法更改节的大小
QHeaderView.ResizeToContents3QHeaderView 将根据整列或整行的内容自动将节调整为最佳大小,用户 以编程方式无法更改节的大小
  • 最后,可以使用 hideSection(logicalIndex: int)和 showSection(logicalIndex: int)隐藏和显示行/列。
    也可以通过 QTableView 的相关函数进行操作使用函数 QTableWidget(QTableView)、resizeColumnsToContents()或 resizeRowsToContents(),根据每列或每行的空间需求分配可用空间,它们会根据每个项目的委托大小提示调整给定行/列的大小,也可以通过函数resizeRowToContents(int)和 resizeColumnToContents(int)指定某个行/列。
拉伸填充剩余空间

在默认情况下,表格中的单元格不会自动扩展以填充剩余空间,可以通过拉伸最后一个标题(行/列)填充剩余空间。使用函数 horizontalHeader0或 verticalHeader0可以获取OHeaderView,并通过 setStretchLastSection(True)函数启用该功能。

表格视图控件QTableView的信号

表格视图控件QTableView的信号如表所示

QTableView的信号及参数类型说 明
activated(QModelIndex)数据项活跃时发送信号
clicked(QModelIndex)单击数据项时发送信号
doubleCIicked(QModelIndex)双击数据项时发送信号
entered(QModelIndex)光标进入数据项时发送信号
iconSizeChanged(QSize)图标尺寸发生变化时发送信号
pressed(QModelIndex)按下鼠标按时发送信号
viewportEntered()光标进入视图控件时发送信号

表格视图控件QTableView的实例

image-20230326230216207

from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *
import sys
import os

os.chdir(os.path.dirname(__file__))


class QTableViewDemo(QMainWindow):
    addCount = 0
    insertCount = 0

    def __init__(self,parent=None):
        super(QTableViewDemo,self).__init__(parent)
        self.setWindowTitle("QTableView案例")
        self.resize(600,800)
        self.text = QPlainTextEdit('用来显示QTableView相关信息:')
        self.tableView = QTableView()
        self.model = QStandardItemModel(5,4)
        self.tableView.setModel(self.model)
        self.selectModel = QItemSelectionModel()
        self.tableView.setSelectionModel(self.selectModel)
        # 设置行列标题
        self.model.setHorizontalHeaderLabels(['标题1','标题2','标题3','标题4'])
        for i in range(4):
            item = QStandardItem(f'行{i + 1}')
            self.model.setVerticalHeaderItem(i,item)

        # 对照组
        self.tableView2 = QTableView()
        self.tableView2.setModel(self.model)

        # 增删行
        self.buttonDeleteRow = QPushButton('删除行')
        self.buttonAddRow = QPushButton('增加行')
        self.buttonInsertRow = QPushButton('插入行')
        layoutH = QHBoxLayout()
        layoutH.addWidget(self.buttonAddRow)
        layoutH.addWidget(self.buttonInsertRow)
        layoutH.addWidget(self.buttonDeleteRow)
        self.buttonAddRow.clicked.connect(lambda: self.onAdd('row'))
        self.buttonInsertRow.clicked.connect(lambda: self.onInsert('row'))
        self.buttonDeleteRow.clicked.connect(lambda: self.onDelete('row'))
        # 增删列
        self.buttonDeleteColumn = QPushButton('删除列')
        self.buttonAddColumn = QPushButton('增加列')
        self.buttonInsertColumn = QPushButton('插入列')
        layoutH2 = QHBoxLayout()
        layoutH2.addWidget(self.buttonAddColumn)
        layoutH2.addWidget(self.buttonInsertColumn)
        layoutH2.addWidget(self.buttonDeleteColumn)
        self.buttonAddColumn.clicked.connect(lambda: self.onAdd('column'))
        self.buttonInsertColumn.clicked.connect(lambda: self.onInsert('column'))
        self.buttonDeleteColumn.clicked.connect(lambda: self.onDelete('column'))

        # 选择
        self.buttonSelectAll = QPushButton('全选')
        self.buttonSelectRow = QPushButton('选择行')
        self.buttonSelectColumn = QPushButton('选择列')
        self.buttonSelectOutput = QPushButton('输出选择')
        layoutH3 = QHBoxLayout()
        layoutH3.addWidget(self.buttonSelectAll)
        layoutH3.addWidget(self.buttonSelectRow)
        layoutH3.addWidget(self.buttonSelectColumn)
        layoutH3.addWidget(self.buttonSelectOutput)
        self.buttonSelectAll.clicked.connect(lambda: self.tableView.selectAll())
        self.buttonSelectRow.clicked.connect(lambda: self.tableView.selectRow(self.tableView.currentIndex().row()))
        self.buttonSelectColumn.clicked.connect(
            lambda: self.tableView.selectColumn(self.tableView.currentIndex().column()))
        self.buttonSelectOutput.clicked.connect(self.onButtonSelectOutput)

        layout = QVBoxLayout(self)
        layout.addWidget(self.tableView)
        # layout.addWidget(self.tableView2)
        layout.addLayout(layoutH)
        layout.addLayout(layoutH2)
        layout.addLayout(layoutH3)
        layout.addWidget(self.text)
        layout.addWidget(self.tableView2)

        widget = QWidget()
        self.setCentralWidget(widget)
        widget.setLayout(layout)

        self.initItem()

        # selection
        # self.listWidget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection)
        # self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectItems)

        # 行列标题
        rowCount = self.model.rowCount()
        columnCount = self.model.columnCount()
        self.model.setHorizontalHeaderLabels([f'col{i}'for i in range(columnCount)])
        self.model.setVerticalHeaderLabels([f'row{i}'for i in range(rowCount)])
        cusHeaderItem = QStandardItem("cusHeader")
        cusHeaderItem.setIcon(QIcon("images/android.png"))
        cusHeaderItem.setTextAlignment(Qt.AlignVCenter)
        cusHeaderItem.setForeground(QColor(255,0,0))
        self.model.setHorizontalHeaderItem(2,cusHeaderItem)

        # 自定义控件
        self.tableView.setIndexWidget(self.model.index(4,3),QLineEdit('自定义控件-'* 3))
        self.tableView.setIndexWidget(self.model.index(4,2),QSpinBox())

        # 调整行列宽高
        header = self.tableView.horizontalHeader()
        # # header.setStretchLastSection(True)
        # # header.setSectionResizeMode(QHeaderView.Stretch)
        # header.setSectionResizeMode(QHeaderView.Interactive)
        # header.resizeSection(3,120)
        # header.moveSection(0,2)

        # header.setStretchLastSection(True)
        self.tableView.resizeColumnsToContents()
        self.tableView.resizeRowsToContents()

        # 排序单元格
        # self.model.sort(1,order=Qt.DescendingOrder)

        # 合并单元格
        self.tableView.setSpan(1,0,1,2)
        item = QStandardItem('合并单元格')
        item.setTextAlignment(Qt.AlignCenter)
        self.model.setItem(1,0,item)

        # 显示坐标
        buttonShowPosition = QToolButton(self)
        buttonShowPosition.setText('显示当前位置')
        self.toolbar.addWidget(buttonShowPosition)
        buttonShowPosition.clicked.connect(self.onButtonShowPosition)

        # 上下文菜单
        self.menu = self.generateMenu()
        self.tableView.setContextMenuPolicy(Qt.CustomContextMenu)######允许右键产生子菜单
        self.tableView.customContextMenuRequested.connect(self.showMenu)####右键菜单

    def initItem(self):

        # 初始化数据
        for row in range(self.model.rowCount()):
            for column in range(self.model.columnCount()):
                value ="row %s,column %s"%(row,column)
                item = QStandardItem(value)
                item.setData(QColor(155,14,0),role=Qt.ForegroundRole)
                item.setData(value + '-toolTip',role=Qt.ToolTipRole)
                item.setData(value + '-statusTip',role=Qt.StatusTipRole)
                item.setData(QIcon("images/open.png"),role=Qt.DecorationRole)
                self.model.setItem(row,column,item)

        # flag+check
        item = QStandardItem('flag+check1')
        item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
        item.setCheckState(Qt.Unchecked)
        self.model.setItem(2,0,item)
        item = QStandardItem('flag+check2')
        item.setFlags(Qt.NoItemFlags)
        item.setCheckState(Qt.Unchecked)
        self.model.setItem(2,1,item)
        # setText
        item = QStandardItem()
        item.setText('右对齐+check')
        item.setTextAlignment(Qt.AlignRight)
        item.setCheckState(Qt.Checked)
        self.model.setItem(3,0,item)
        # setIcon
        item = QStandardItem(f'setIcon')
        item.setIcon(QIcon('images/music.png'))
        item.setWhatsThis('whatsThis提示1')
        self.model.setItem(3,1,item)
        # setFont、setFore(Back)ground
        item = QStandardItem(f'setFont、setFore(Back)ground')
        item.setFont(QFont('宋体'))
        item.setForeground(QBrush(QColor(255,0,0)))
        item.setBackground(QBrush(QColor(0,255,0)))
        self.model.setItem(3,2,item)
        # setToolTip,StatusTip,WhatsThis
        item = QStandardItem(f'提示帮助')
        item.setToolTip('toolTip提示')
        item.setStatusTip('statusTip提示')
        item.setWhatsThis('whatsThis提示2')
        self.model.setItem(3,3,item)

        # 开启statusbar
        statusBar = self.statusBar()
        statusBar.show()
        self.tableView.setMouseTracking(True)

        # 开启whatsThis功能
        whatsThis = QWhatsThis(self)
        self.toolbar = self.addToolBar('help')
        #    方式1:QAction
        self.actionHelp = whatsThis.createAction(self)
        self.actionHelp.setText('显示whatsThis-help')
        self.actionHelp.setShortcuts(QKeySequence(Qt.CTRL | Qt.Key_H))
        self.toolbar.addAction(self.actionHelp)
        #   方式2:工具按钮
        tool_button = QToolButton(self)
        tool_button.setToolTip("显示whatsThis2-help")
        tool_button.setIcon(QIcon("images/help.jpg"))
        self.toolbar.addWidget(tool_button)
        tool_button.clicked.connect(lambda: whatsThis.enterWhatsThisMode())

        self.model.setData(self.model.index(4,0),QColor(215,214,220),role=Qt.BackgroundRole)

    def generateMenu(self):
        menu = QMenu(self)
        menu.addAction('增加行',lambda: self.onAdd('row'),QKeySequence(Qt.CTRL | Qt.Key_N))
        menu.addAction('插入行',lambda: self.onInsert('row'),QKeySequence(Qt.CTRL | Qt.Key_I))
        menu.addAction(QIcon("images/close.png"),'删除行',lambda: self.onDelete('row'),QKeySequence(Qt.CTRL | Qt.Key_D))
        menu.addSeparator()
        menu.addAction('增加列',lambda: self.onAdd('column'),QKeySequence(Qt.CTRL | Qt.SHIFT | Qt.Key_N))
        menu.addAction('插入列',lambda: self.onInsert('column'),QKeySequence(Qt.CTRL | Qt.SHIFT | Qt.Key_I))
        menu.addAction(QIcon("images/close.png"),'删除列',lambda: self.onDelete('column'),
                       QKeySequence(Qt.CTRL | Qt.SHIFT | Qt.Key_D))
        menu.addSeparator()
        menu.addAction('全选',lambda: self.tableView.selectAll(),QKeySequence(Qt.CTRL | Qt.Key_A))
        menu.addAction('选择行',lambda: self.tableView.selectRow(self.tableView.currentIndex().row()),
                       QKeySequence(Qt.CTRL | Qt.Key_R))
        menu.addAction('选择列',lambda: self.tableView.selectColumn(self.tableView.currentIndex().column()),
                       QKeySequence(Qt.CTRL | Qt.SHIFT | Qt.Key_R))
        menu.addAction('输出选择',self.onButtonSelectOutput)
        menu.addSeparator()
        menu.addAction(self.actionHelp)
        menu.addAction('显示当前位置',lambda: self.onButtonShowPosition())
        return menu

    def showMenu(self,pos):
        self.menu.exec(QCursor.pos())# 显示菜单

    def contextMenuEvent(self,event):
        menu = QMenu(self)
        menu.addAction('选项1')
        menu.addAction('选项2')
        menu.addAction('选项3')
        menu.exec(event.globalPos())

    def onButtonSelectOutput(self):

        indexList = self.tableView.selectedIndexes()
        _row = indexList[0].row()
        text = ''
        for index in indexList:
            row = index.row()
            column = index.column()
            item = self.model.item(row,column)
            if _row == row:
                text = text + item.text()+ ''
            else:
                text = text + '\n'+ item.text()+ ''
                _row = row
        self.text.appendPlainText(text)

    def onAdd(self,type='row'):
        if type == 'row':
            rowCount = self.model.rowCount()
            self.model.insertRow(rowCount)
            # self.tableView.insertRow(rowCount)
            self.text.appendPlainText(f'row:{rowCount},新增一行')
        elif type == 'column':
            columnCount = self.model.columnCount()
            self.model.insertColumn(columnCount)
            self.text.appendPlainText(f'column:{columnCount},新增一列')

    def onInsert(self,type='row'):
        index = self.tableView.currentIndex()
        if type == 'row':
            row = index.row()
            self.model.insertRow(row)
            self.text.appendPlainText(f'row:{row},插入一行')
        elif type == 'column':
            column = index.column()
            self.model.insertColumn(column)
            self.text.appendPlainText(f'column:{column},新增一列')

    def onDelete(self,type='row'):
        index = self.tableView.currentIndex()
        if type == 'row':
            row = index.row()
            self.model.removeRow(row)
            self.text.appendPlainText(f'row:{row},被删除')
        elif type == 'column':
            column = index.column()
            self.model.removeColumn(column)
            self.text.appendPlainText(f'column:{column},被删除')

    def onButtonShowPosition(self):
        index = self.tableView.currentIndex()
        row = index.row()
        rowPositon = self.tableView.rowViewportPosition(row)
        rowAt = self.tableView.rowAt(rowPositon)
        column = index.column()
        columnPositon = self.tableView.columnViewportPosition(column)
        columnAt = self.tableView.columnAt(columnPositon)
        _str = f'当前row:{row},rowPosition:{rowPositon},rowAt:{rowAt}'+ \
               f'\n当前column:{column},columnPosition:{columnPositon},columnAt:{columnAt}'
        self.text.appendPlainText(_str)


if __name__ =="__main__":
    app = QApplication(sys.argv)
    demo = QTableViewDemo()
    demo.show()
    sys.exit(app.exec())

PyQt5的Model/View是一种用于创建用户界面的框架。它基于MVC(Model-View-Controller)设计模式,提供了一种将数据和界面分离的方法。 Model/View框架中,Model负责管理和提供数据,View负责数据的可视化展示,而两者之间由Controller进行交互。 在PyQt5中,Model通常是QAbstractItemModel类或其子类的实例。它提供了一种标准的接口,用于管理和操作数据。通过Model,我们可以对数据进行添加、删除和修改等操作,并在这些操作之后通知View进行更新。 View则是用户界面上的部件,如QTreeViewQTableView或QListView等。它负责将Model中的数据以视觉化的方式展示给用户,并根据用户的操作与Model进行交互。View会通过信号与槽机制、或直接获取Model的数据来更新界面。 在Model/View框架中,ModelView之间是通过索引(Index)进行连接的。索引是一个由Model提供的标识,用于标记数据的位置和层级关系。View在显示数据时,会根据索引来获取数据的值,并根据需要进行格式化或呈现。 通过Model/View框架,我们可以实现数据和界面的解耦合,通过更改Model中的数据来自动更新界面。同时,Model/View也提供了一些方便的方法和信号,用于处理数据的排序、过滤和选择等操作。 总而言之,PyQt5的Model/View是一种用于创建用户界面的框架,可以通过数据模型和视图来管理和展示数据。它可以使用户界面更加直观、灵活和易于维护。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

士别三日,当挖目相待

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值