【问题标题】:Python PyQt - MVC Pattern - Model Class To Work With View and ObjectPython PyQt - MVC 模式 - 使用视图和对象的模型类
【发布时间】:2013-05-27 11:38:12
【问题描述】:

我正在尝试以 MVC 模式学习 pyQt 编程(在 QT 中没有控制器,所以实际上只有模型/视图)。我有 try1.py,这是我从 QT 设计器制作的图形。在那,我有 2 行编辑框 - 用户名和密码。然后我有 test.py 这是实际的 python 脚本。

1) 由于文本行小部件嵌套在全局 Ui_Form 中......我如何将模型分配给它们?通常我会使用widgetView = setModel(model) 之类的东西,但我不知道如何使用self.lineEdit = QtGui.QLineEdit(Form) 来做到这一点。由于我正在尝试使用 MVC,我认为这需要在 Ui_Form 类之外?

2) 我会有 2 个不同的模型 - 1 个用于用户名小部件,1 个用于密码?

3) 如何让 TextLineModel 更新 X 对象实例中的字段并更新视图?

这是pyuic.py已经编译好的try1.py QT Editor:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'try1.ui'
#
# Created: Mon May 27 04:00:05 2013
#      by: PyQt4 UI code generator 4.10.1
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

    class Ui_Form(object):
        def setupUi(self, Form):
            Form.setObjectName(_fromUtf8("Form"))
            Form.resize(640, 480)
            self.label = QtGui.QLabel(Form)
            self.label.setGeometry(QtCore.QRect(100, 30, 71, 16))
            self.label.setObjectName(_fromUtf8("label"))
            self.label_2 = QtGui.QLabel(Form)
            self.label_2.setGeometry(QtCore.QRect(100, 60, 61, 16))
            self.label_2.setObjectName(_fromUtf8("label_2"))
            self.lineEdit = QtGui.QLineEdit(Form)
            self.lineEdit.setGeometry(QtCore.QRect(160, 30, 231, 20))
            self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
            self.lineEdit_2 = QtGui.QLineEdit(Form)
            self.lineEdit_2.setGeometry(QtCore.QRect(160, 60, 231, 20))
            self.lineEdit_2.setObjectName(_fromUtf8("lineEdit_2"))
            self.verticalLayoutWidget = QtGui.QWidget(Form)
            self.verticalLayoutWidget.setGeometry(QtCore.QRect(80, 20, 361, 81))
            self.verticalLayoutWidget.setObjectName(_fromUtf8("verticalLayoutWidget"))
            self.verticalLayout_2 = QtGui.QVBoxLayout(self.verticalLayoutWidget)
            self.verticalLayout_2.setMargin(0)
            self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))

            self.retranslateUi(Form)
            QtCore.QMetaObject.connectSlotsByName(Form)

        def retranslateUi(self, Form):
            Form.setWindowTitle(_translate("Form", "Form", None))
            self.label.setText(_translate("Form", "UserName:", None))
            self.label_2.setText(_translate("Form", "Password:", None))

这是脚本 test.py 脚本:

import sys
from PyQt4 import QtCore, QtGui

from untitled import Ui_Form
from collections import OrderedDict

class GetInfo():
    def __init__(self):
        self.info = OrderedDict([('userName', None),
                     ('passWord', ' ')]

    def login_name(self):
        name = raw_input("Enter Login Name: ")
        self.login_info["login_name"] = name

    def password(self):
        name = raw_input("Enter Password: ")
        self.login_info["password"] = name


class TextLineModel(QtCore.QAbstractListModel):
        def __init__(self, text, parent = none):
             QtCore.QAbstractListModel.__init__(self, parent)
             self._text = text

         def data(self, index, roll):
                if role == QtCore.Qt.DisplayRole:
                    value = self._text
                    return value



class MyForm(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_Form()
        self.ui.setupUi(self)


if __name__ == "__main__":
    x = GetInfo()
    app = QtGui.QApplication(sys.argv)
    myapp = MyForm()
    myapp.show()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python model-view-controller pyqt


    【解决方案1】:

    1) 您必须使用QDataWidgetmapper 链接您的模型和小部件。

    2) 不,您应该为单一类别的数据建立单一模型。在您的情况下,它应该是QAbstractTablemodel

    3)您可以调用QDataWidgetmapper.revert() 来使用模型中的数据更新小部件。模型要么在用户完成小部件编辑后自动更新,要么通过手动调用QDataWidgetmapper.submit()(参见QDataWidgetmapper.submitPolicy

    【讨论】:

    • 应该没什么区别。文档here
    • 在这种情况下实际上并不重要 :) Qt 模型\视图框架是 Qt 的一部分。您使用何种绑定来访问它并不重要。但是为了让你放心goes
    • 将初始化放在应该在的位置 - MyForm.__init__()。创建模型和小部件映射器的实例,并使它们成为您的 MyForm 实例的成员。然后调用 self.mapper.setModel(self.model) 并等待几分钟,我想出一个可行的例子。
    • 好吧,你的任务是创建模型并用数据填充它。填充模型的那一刻取决于您 - 例如,您可以在创建表单时执行此操作。或者您可以在表单上放置一个刷新按钮。或者等待一些信号或事件。这完全取决于您的应用程序。在最简单的情况下,您应该将其放入 MyForm.__init__()。在我的示例中,它发生在第 52-58 行。创建并填充数据的模型,与 QDataWidgetMapper 链接的模型 - 告诉映射器获取第一行(顺便说一句,这是必不可少的步骤)
    • 啊,忘了添加 - 模型不是数据存储,它只是您的自定义数据结构(在本例中 - 用户实例列表)和小部件\视图之间的强形式化接口。当小部件被编辑时,他们调用 mapper 并调用 model.setData(UserDataFromAWidget)。然后模型将数据放入您的数据存储中,如您在 model.setData() 中所述。如果你没有重新定义 setData(),什么都不会发生。没有魔法 - 你必须明确告诉模型如何读取和写入数据到你的数据存储 - 通过重新定义 data() 和 setData()。
    猜你喜欢
    • 1970-01-01
    • 2010-12-12
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    相关资源
    最近更新 更多