PyQt et MVC-pattern

s'il vous Plaît, m'aider avec la conception MVC-modèle avec PyQt. Je veux diviser tous les programme en 3 parties:

  1. une classe abstraite de toutes les classes de Qt(modèle)
  2. un peu de classe qui fournit des données d'un modèle à l'allongement de l'application(contrôleur)
  3. QT-app elle-même avec méthode définie SignalsToSlots qui connectent les signaux avec le contrôleur.

est-ce optimal et quel schéma utilise-t-on dans le développement du PyQt?

P. S.: Désolé pour mon anglais =)

28
demandé sur Macke 2009-11-02 13:27:34

3 réponses

une des premières choses que vous devez faire est d'utiliser Qt4 designer pour concevoir votre interface graphique et d'utiliser pyuic4 pour générer votre interface graphique python. Ce sera votre vue, vous ne modifiez jamais ces fichiers python à la main. Toujours faire des changements en utilisant designer, ce qui garantit que votre vue est séparée de votre modèle et de contrôle.

pour l'élément de contrôle, créez une classe centrale qui hérite de votre widget gui de base tel que QMainWindow. Cet objet sera alors contient un membre de l'interface utilisateur qui est votre point de vue l'objet que vous venez de générer.

voici un exemple de un tutoriel

mise à jour 2013: voici un tutoriel(s) Plus Récent (s) sur le modèle PyQt et MVC PyQt MVC Tutorial Series

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_())

le point clé dans l'exemple ci-dessus est que le contrôleur contient l'ui et ne l'hérite pas directement. Le contrôleur sera responsable de gérer les connexions de slots de signal pour votre interface graphique et de fournir une interface pour vos données. modèle.

pour décrire la partie model dont nous avons besoin d'un exemple, supposons que votre projet est de créer une base de données de collection de films. Le modèle inclurait les objets internes qui représentent des films individuels, ainsi que les objets qui représentent des listes de films. Vous contrôlez prendrait les données entrées de la vue et attraper les signaux, puis les valider avant de demander au modèle de se mettre à jour. Cette partie est cruciale, le contrôleur ne doit pas accéder directement au modèle si possible, il devrait demander au modèle d'y accéder lui-même.

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!

il est également important dans MVC pour centraliser l'accès, dire que l'utilisateur peut changer le titre en double cliquant dessus sur l'écran, ou en cliquant éditer à côté du champ Titre, de ces interfaces doivent finir utilisant la même méthode pour le changement. Et par ça, Je ne veux pas dire que chacun appelle un film.update_title(titre). Je veux dire que les deux signaux devraient utiliser la même méthode dans le contrôleur.

essayez autant que possible de faire toutes les relations entre la vue et le contrôleur beaucoup à 1. Sens, c'est que vous avez 5 façons de changer quelque chose dans l'interface graphique, ont 1 méthode dans le contrôleur pour gérer cela. Si les fentes ne sont pas tous compatibles que créer des méthodes pour chacune des méthodes qui appellent alors une seule méthode. Si vous résolvez le problème 5 fois pour 5 styles de vue alors il n'y a vraiment pas et raison de se séparer le point de vue du contrôle. Aussi, puisque vous avez maintenant une seule façon de faire quelque chose dans le contrôleur vous ai un nice 1-1 relation entre le contrôle et le modèle.

en ce qui concerne le fait d'avoir votre modèle complètement séparé de Qt, ce n'est pas vraiment nécessaire et cela peut rendre la vie plus difficile pour vous. L'utilisation de choses comme QStrings dans votre modèle peut être commode, et si dans une autre application vous ne voulez pas la tête d'une interface graphique, mais voulez que les modèles importent QtCore seulement. J'espère que ce aide!

41
répondu cmaynard 2013-05-22 09:07:16

Oui, PyQt utilise le concept de Model / View (officiellement sans la partie" Controller"), mais il se peut que vous ayez une image quelque peu déformée de ce que cela signifie Dans PyQt.

Il y a deux parties:

  1. Modèles, sous-classé de PyQt base de modèle abstrait classes (QAbstractItemModel,QAbstractTableModel,QAbstractListModel, etc.). Ces modèles peuvent s'adresser directement à vos sources de données (fichiers, bases de données), ou se substituer à vos propres modèles PyQt-agnostiques qui ont été écrits avant.
  2. vues, qui sont implémentées dans la bibliothèque Qt, et ne nécessitent souvent aucune modification (exemples:QTreeView,QTableView et autres). Même certains contrôles plus simples, comme QComboBox peut agir comme une vue pour un modèle PyQt.

toutes les autres parties de votre application qui réagissent aux signaux,etc. peut être considéré comme "contrôleur".

PyQt fournit également un ensemble de modèles prédéfinis "universels" qui peuvent être sous-Classés ou utilisés directement si vous avez besoin seulement fonctionnalité simple du modèle, comme QStringListModel,QStandardItemModel, etc. Et il y a aussi des modèles qui peuvent parler directement aux bases de données, comme QSqlTableModel.

6
répondu abbot 2009-11-07 12:33:25

voici un lien vers le guide officiel et détaillé sur la façon dont l'architecture Qt offre une vue Modèle à une application

http://doc.qt.io/qt-5/model-view-programming.html

dans Qt, view et controller sont combinés, donc une application peut être conçue en utilisant Model-View framework.

le modèle communique avec une source de données, fournissant une interface pour les autres composants dans l'architecture. La nature de l' la communication dépend du type de source de données et de la modèle est mis en œuvre. La vue obtient des index de modèle du modèle; ce sont les références aux éléments de données. En fournissant des index de modèles le modèle, la vue peut récupérer des éléments de données de la source de données. Dans les vues standard, un délégué rend les éléments de données. Lorsqu'un élément est édité, le délégué communique directement avec le modèle en utilisant modèle d'index.

...

les modèles, les vues et les délégués communiquent entre eux à l'aide de signaux et de slots

3
répondu Jayesh 2015-06-25 00:30:10