[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的功能

扫描二维码关注公众号,回复: 8745831 查看本文章

两个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

我们在修改数据时,都是在编辑状态下,

发布了56 篇原创文章 · 获赞 1 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_41363156/article/details/104039579