Первое, что вы должны сделать, это использовать Qt4 designer для разработки вашего графического интерфейса и использовать pyuic4 для генерации вашего Python GUI. Это будет ваш взгляд, вы НИКОГДА не редактируете эти файлы python вручную. Всегда вносите изменения с помощью конструктора, это гарантирует, что ваш View будет отделен от вашей модели и элемента управления.
Для элемента управления создайте центральный класс, который наследуется от вашего базового графического виджета, такого как QMainWindow. Затем этот объект будет содержать пользовательский интерфейс, который является вашим сгенерированным объектом просмотра.
вот пример из учебника
ОБНОВЛЕНИЕ 2013: Вот более свежие уроки по PyQt и модели MVC
Серия учебных пособий по PyQt MVC
import sys
from PyQt4 import QtCore, QtGui
from edytor import Ui_notepad
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_notepad()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = StartQT4()
myapp.show()
sys.exit(app.exec_())
Ключевым моментом в приведенном выше примере является то, что контроллер содержит пользовательский интерфейс и не наследует его напрямую. Контроллер будет отвечать за управление соединениями сигнальных слотов для вашего графического интерфейса и предоставление интерфейса для вашей модели данных.
Чтобы описать часть модели, нам нужен пример, давайте предположим, что ваш проект состоит в создании базы данных коллекции фильмов. Модель будет включать внутренние объекты, которые представляют отдельные фильмы, а также объекты, которые представляют списки фильмов. Вы управляете тем, что берете данные, введенные из вида, и ловите сигналы, затем проверяете их, прежде чем просить модель обновить себя. Эта часть имеет решающее значение, контроллер не должен напрямую обращаться к модели, если это вообще возможно, он должен запрашивать модель для доступа к себе.
Вот небольшой пример этого взаимодействия (непроверенный, возможно, некоторые опечатки):
class Movie():
def __init__(self,title=None,year=None,genre=None):
self.title=title
self.year=year
self.genre=genre
def update(self,title=None,year=None,genre=None):
self.title=title
self.year=year
self.genre=genre
def to_xml(self,title=None,date=None,genre=None):
pass #not implementing this for an example!
#when the controller tries to update it should use update function
movie1.update("Manos Hands Of Fate",1966,"Awesome")
#don't set by direct access, your controller shouldn't get that deep
movie1.title="Bad Idea" #do not want!
В MVC также важно централизовать доступ, например, пользователь может изменить заголовок, дважды щелкнув его на экране, или щелкнув по значку «Изменить» рядом с полем заголовка, оба этих интерфейсов должны завершиться используя тот же метод для изменения. И под этим я не подразумеваю, что каждый вызывает movie.update_title (title). Я имею в виду, что оба сигнала должны использовать один и тот же метод в контроллере.
Постарайтесь сделать все возможное, чтобы все отношения между View и контроллером были много к 1. Это означает, что у вас есть 5 способов что-то изменить в графическом интерфейсе, для этого есть 1 метод в контроллере. Если слоты не все совместимы, то создайте методы для каждого из методов, которые затем вызывают один единственный метод. Если вы решите проблему 5 раз для 5 стилей представления, то на самом деле нет и причины отделять представление от элемента управления. Кроме того, поскольку теперь у вас есть только один способ сделать что-то в контроллере, у вас хорошие отношения 1: 1 между элементом управления и моделью.
Поскольку ваша модель полностью отделена от Qt, в этом нет необходимости, и она может фактически осложнить вам жизнь. Использование таких вещей, как QStrings, в вашей модели может быть удобным, и если в другом приложении вы не хотите использовать накладные расходы на графическом интерфейсе, а хотите, чтобы модели просто импортировали только QtCore. Надеюсь, это поможет!