Model/View框架简介
Model-View-Controller(MVC), 是从Smalltalk发展而来的一种设计模式,常被用于构建用户界面。在设计模式中对MVC模式的描述如下:MVC由3种对象组成:模型是应用程序对象,视图是它的屏幕显示方式,控制器定义用户接口对用户输入反应的方式。在MVC设计模式之前,用户界面设计倾向于三者揉合在一起,MVC对它们进行了解耦,提高了灵活性与重用性。
MVC 由三种对象组成,Model负责维护数据(如管理数据库),View负责显示与用户交互(如各种界面),Controller将控制业务逻辑。如果把View与Controller结合在一起,结果就是Model/View框架。Model/View框架依然是把数据存储与数据表示进行了分离,与MVC都基于同样的思想,但更简单。数据存储与数据显示的分离使得在几个不同的View上显示同一个数据成为可能,也可以重新实现新的View,而不必改变底层的数据结构。为了更灵活的对用户输入进行处理,引入了Delegate,使得数据项的传递与编辑可以进行定制。
Model负责与数据源通讯,并提供接口给结构中的别的组件使用。通讯的实质依赖于数据源的类型与Model实现的方式。
View从Model获取模型索引,模型索引是数据项的引用。通过把模型索引提供给Model,View可以从数据源中获取数据。
关于Model/View框架详细介绍可参考QT开发(三十七)——Model/View官方文档(中文翻译)或Model/View Programming(Qt for Python 5.15.2官方英文介绍)
需求描述
继承QAbstractTableModel
类,创建自定义Model
,用于保存表格类数据,供QtableView
、QChart
等视图调用显示。
开发环境
Python3.7
PySide2
Windows10
代码
import sys
import pandas as pd
from PySide2.QtWidgets import QApplication, QWidget, QTableView, QHeaderView, QHBoxLayout
from PySide2.QtCore import QAbstractTableModel, QModelIndex, Qt
class ResultDataModel(QAbstractTableModel):
def __init__(self, data=pd.DataFrame()):
QAbstractTableModel.__init__(self)
self.__data = data
self.__hHeader = self.__data.columns.tolist()
self.__vHeader = self.__data.index.tolist()
def rowCount(self, parent=QModelIndex()):
return self.__data.shape[0]
def columnCount(self, parent=QModelIndex()):
return self.__data.shape[1]
def data(self, index: QModelIndex, role=Qt.DisplayRole):
if not index.isValid():
return None
if role == Qt.TextAlignmentRole:
return Qt.AlignCenter
if role == Qt.DisplayRole:
return str(self.__data.iloc[index.row()][index.column()])
return None
def headerData(self, section, orientation, role):
if role != Qt.DisplayRole:
return None
if orientation == Qt.Horizontal:
return self.__hHeader[section]
elif orientation == Qt.Vertical:
return self.__vHeader[section]
class Test(QWidget):
def __init__(self):
QWidget.__init__(self)
self.setMinimumSize(800, 500)
df = pd.DataFrame([[1, 2, 3, 4], [5, 6, 7, 8]], index=['A', 'B'], columns=['One', 'Two', 'Three', 'Four'])
print(df)
self.tableModel = ResultDataModel(df)
self.tableView = QTableView()
self.tableView.setModel(self.tableModel)
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.tableView.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)
layout = QHBoxLayout()
layout.addWidget(self.tableView)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
widget = Test()
widget.resize(1000, 800)
widget.show()
sys.exit(app.exec_())
注意事项
代码第26
行return str(self.__data.iloc[index.row()][index.column()])
中,必须将返回结果通过str()
函数转变为字符串,否则无法显示数据。
运行效果
参考资料
以上,欢迎交流~