[Pyqt]一、MVC

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

我們在修改數據時,都是在編輯狀態下。

發佈了59 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章