MVC
mvc不僅僅是qt裏面的概念,(Model View Controler)的簡稱
Model是一個數據模型、一個虛擬的東西,顯示不出來的,如果我們要把這些數據顯示出來,就需要使用view
view:用來顯示Model這種數據
controler:如果我們要編輯數據,就需要使用controler
不使用controler,我們只能對數據進行查看不能編輯
就像我們去火車站買票,可以看到火車站有一個大屏幕,顯示現在的票量,它後臺的數據庫就可以當作一個Model,一個數據模型,大顯示器就像一個View,它可以顯示後臺的數據,現在有多少票,還剩下多少票,而且是實時動態刷新的,櫃檯裏的電腦也可以是一個view,可以多個view顯示同一個model,也就是說同一個數據模型,可以在不同的view上顯示。那麼在某一個view上面編輯了model數據,那麼所有的view都會刷新這個數據
在pyqt中,view包括List View、Tree View、Table View、Column View
首先我們創建含有兩個List View的UI佈局:
List Widget:含有一些常用的功能,可以在屬性編輯中處理元素
List View:沒有屬性設置,僅提供了view窗口,需要加上數據模型,通過分開控制,可以實現高度自定義
接下來就用List View來實現List Widget的功能
兩個List View是沒有任何區別的,兩個List View使用同一個數據模型
Designer.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'mvc.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(625, 385)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.widget = QtWidgets.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(32, 24, 525, 218))
self.widget.setObjectName("widget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.label = QtWidgets.QLabel(self.widget)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.listView1 = QtWidgets.QListView(self.widget)
self.listView1.setObjectName("listView1")
self.verticalLayout.addWidget(self.listView1)
self.horizontalLayout.addLayout(self.verticalLayout)
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.label_2 = QtWidgets.QLabel(self.widget)
self.label_2.setObjectName("label_2")
self.verticalLayout_2.addWidget(self.label_2)
self.listView_2 = QtWidgets.QListView(self.widget)
self.listView_2.setObjectName("listView_2")
self.verticalLayout_2.addWidget(self.listView_2)
self.horizontalLayout.addLayout(self.verticalLayout_2)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 625, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "List View"))
self.label_2.setText(_translate("MainWindow", "List Widget"))
view.py
# coding=utf-8
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from b.MVC.mvc import Ui_MainWindow
from b.MVC.mvc_core import ListMode
class DemonWindow(Ui_MainWindow, QtWidgets.QMainWindow):
"""
創建list model
"""
def __init__(self, parent=None):
super(Ui_MainWindow, self).__init__(parent)
self.setupUi(self)
self.list_model = ListMode(self.listView1)
self.listView1.setModel(self.list_model)
self.listView_2.setModel(self.list_model)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv) # sys.argv是一組命令行參數的列表,該程序會被cou進行輪詢
ex = DemonWindow()
ex.show()
app.exec_()
4,從Model中創建一個Model
self.list_model = ListMode(self.listView1)
僅創建一個Model,Model和View還沒有產生關係,在我們實際編寫過程中,我們的數據模型一定要寫程實例的屬性,這個實例我們要放在self下面,否則,在其他的方法裏要操作這個模型的話,就訪問不到了
5.將List View1的模型設置爲上面實例化的self.list_model
self.listView1.setModel(self.list_model)
Model.py:
# coding=utf-8
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
class ListMode(QtCore.QAbstractListModel):
"""
創建list model
"""
def __init__(self, parent=None):
super(ListMode, self).__init__(parent)
self.list_data = list("ABCDE")
def rowCount(self, parent=QtCore.QModelIndex()):
"""
:param self:
:param parent:
:param args:
:param kwargs:
:return:
"""
return len(self.list_data)
def data(self, index = QtCore.QModelIndex(), role=QtCore.Qt.DisplayRole):
"""
:param QModelIndex:
:param role:
:return:
"""
if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
return self.list_data[index.row()]
# 設置前景色
if role == QtCore.Qt.ForegroundRole:
return QtGui.QColor(255, 0, 0)
# 設置背景色
if role == QtCore.Qt.BackgroundColorRole:
return QtGui.QColor(0, 255, 0)
def flags(self, index=QtCore.QModelIndex()):
"""
:param index:
:return:
"""
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
def setData(self, index = QtCore.QModelIndex(), value=None, role=QtCore.Qt.EditRole):
"""
:param QModelIndex:
:param value:
:param role:
:return:
"""
if value != None:
self.list_data[index.row()] = value
self.dataChanged.emit(index, index)
return True
1.QtCore.QAbstractListModel繼承自QtCore.QAbstractItemModel,與之對應的還有QtCore.QAbstractTableModel針對List View使用QtCore.QAbstractListModel就可以了,使用QtCore.QAbstractItemModel也可以,但是我們要寫更多的方法
創建完一個QtCore.QAbstractListModel,本身是不知道誰要用它,所以沒有一個基本的數據,直接用QtCore.QAbstractListModel是用不了的,所以我們要繼承他,來寫一個自己的模型
2.導入QT.Core
from PyQt5 import QtCore
我們的數據模型實際上一個不能顯示的東西,是一個虛擬的東西,只能在後臺有一層數據,但是顯示不出來,在QT中,能顯示的都是QWidgets,像圖標之類的都是GUI,純數據類型的就是Qt.Core裏邊的。
3.創建一個LIst Model繼承自QtCore.QAbstractListModel
初始化函數,創建一個單純的Model
# coding=utf-8
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
class ListMode(QtCore.QAbstractListModel):
"""
創建list model
"""
def __init__(self, parent=None):
super(ListMode, self).__init__(parent)
6.添加rowCount(self, parent=QtCore.QModelIndex()),並設置返回值5
def rowCount(self, parent=QtCore.QModelIndex()):
"""
:param self:
:param parent:
:param args:
:param kwargs:
:return:
"""
return 5
我們設置了行數,但是每行裏要顯示的數據還沒有,接下來我們定義數據
7.添加data(self, index = QtCore.QModelIndex(), role=QtCore.Qt.DisplayRole),role爲一種顯示狀態
def data(self, index = QtCore.QModelIndex(), role=QtCore.Qt.DisplayRole):
"""
:param QModelIndex:
:param role:
:return:
"""
if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
return 0
8.添加flags(self, index=QtCore.QModelIndex()),狀態激活,是否可以選擇、是否可以拖拽
def flags(self, index=QtCore.QModelIndex()):
"""
:param index:
:return:
"""
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
在model中, index是經常用到的,涉及到行列及上下關係,他並不是一個整數
9.設置setdata,數據修改,
def setData(self, index = QtCore.QModelIndex(), value=None, role=QtCore.Qt.EditRole):
"""
:param QModelIndex:
:param value:
:param role:
:return:
"""
if value != None:
self.list_data[index.row()] = value
self.dataChanged.emit(index, index)
return True
我們在修改數據時,都是在編輯狀態下。