Eines der ersten Dinge, die Sie tun sollten, ist Qt4 Designer zu verwenden, um Ihre GUI zu entwerfen und pyuic4 zu verwenden, um Ihre Python-GUI zu generieren. Dies wird Ihre Ansicht sein, Sie werden diese Python-Dateien NIEMALS von Hand bearbeiten. Nehmen Sie Änderungen immer mit dem Designer vor, so ist sichergestellt, dass Ihre View von Ihrem Model und Control getrennt ist.
Erstellen Sie für das Steuerelement eine zentrale Klasse, die von Ihrem Basis-GUI-Widget wie QMainWindow erbt. Dieses Objekt wird dann enthalten ein Mitglied ui, die Ihre Ansicht Objekt, das Sie gerade generiert ist.
Hier ist ein Beispiel aus eine Anleitung
UPDATE 2013: Hier ist ein neueres Tutorial über PyQt und MVC Model PyQt MVC Lehrgangsreihe
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_())
Der entscheidende Punkt im obigen Beispiel ist, dass der Controller die Benutzeroberfläche enthält und sie nicht direkt erbt. Der Controller ist für die Verwaltung von Signalsteckplatzverbindungen für die Benutzeroberfläche und die Bereitstellung einer Schnittstelle zu Ihrem Datenmodell verantwortlich.
Um den Modellteil zu beschreiben, benötigen wir ein Beispiel. Nehmen wir an, Ihr Projekt besteht darin, eine Datenbank für Filmsammlungen zu erstellen. Das Modell würde die internen Objekte enthalten, die einzelne Filme darstellen, sowie Objekte, die Listen von Filmen repräsentieren. Ihr Steuerelement würde die von der Ansicht eingegebenen Daten entgegennehmen, die Signale abfangen und sie dann validieren, bevor das Modell aufgefordert wird, sich selbst zu aktualisieren. Dieser Teil ist entscheidend, der Controller sollte nicht direkt auf das Modell zugreifen, wenn überhaupt möglich, sollte es das Modell bitten, sich selbst zugreifen.
Hier ist ein kleines Beispiel dieser Interaktion (nicht getestet, kann einige Tippfehler enthalten):
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!
In MVC ist es auch wichtig, den Zugriff zu zentralisieren, d.h. der Benutzer kann den Titel durch Doppelklick auf dem Bildschirm oder durch Klicken auf "Bearbeiten" neben dem Titelfeld ändern, beide dieser Schnittstellen sollten am Ende die gleiche Methode für die Änderung verwenden. Und damit meine ich nicht, dass jede dieser Schnittstellen movie.update_title(title) aufruft. Ich meine, dass beide Signale die gleiche Methode im Controller verwenden sollten.
Versuchen Sie so weit wie möglich, alle Beziehungen zwischen der Ansicht und dem Controller viele zu 1 zu machen. Das bedeutet, dass Sie 5 Möglichkeiten haben, etwas in der Benutzeroberfläche zu ändern, haben 1 Methode in der Steuerung, dies zu behandeln. Wenn die Slots nicht alle kompatibel sind, erstellen Sie Methoden für jede der Methoden, die dann eine einzige Methode aufrufen. Wenn Sie das Problem lösen 5 mal für 5 Ansichtsstile dann gibt es wirklich nicht und Grund, um die Ansicht von der Steuerung zu trennen. Da Sie jetzt nur eine Möglichkeit haben, etwas im Controller zu tun, haben Sie eine schöne 1 zu 1 Beziehung zwischen Control und Model.
Was die vollständige Trennung Ihres Modells von Qt betrifft, so ist dies nicht wirklich notwendig und kann Ihnen das Leben sogar erschweren. Mit Dingen wie QStrings in Sie Modell kann bequem sein, und wenn in einer anderen Anwendung, die Sie nicht wollen, den Overhead eines Gui aber die Modelle nur importieren QtCore. Hoffentlich hilft das!