Je pense que la terminologie utilisée dans Qt avec les commandes modèle / vue est imparfaite. Sur leur page d'explication, ils déclarent qu'ils ont simplifié MVC en MV en fusionnant View et Controller et ils donnent l'image suivante:
Cependant je pense qu'ils ont mal nommé les rôles des objets et je pense que,
- Ce qu'ils appellent la vue avec le contrôleur fusionné est en fait une vue uniquement.
- Ce qu'ils appellent Model n'est en fait que Controller.
- Si vous voulez vraiment avoir un modèle, ce serait quelque part où se trouvent leurs «données».
Je parle de la manière habituelle et sensée d'utiliser le composant modèle / vue Qt dans votre application. Voici les raisons:
- Il s'agit généralement d'un composant Qt qui est utilisé tel quel, sans ajouter de logique de contrôleur spécifique à vos objets)
- Ce n'est guère un modèle, simplement parce que vous devez implémenter plusieurs méthodes Qt comme rowCount, columnCount, data etc. qui n'ont rien à voir avec votre modèle. En fait, il existe des méthodes de modèle typiques trouvées dans les contrôleurs. Bien sûr, vous pouvez implémenter à la fois la logique du contrôleur et du modèle ici, mais d'abord, ce serait une conception de code assez mauvaise et deuxièmement, vous fusionneriez contrôleur et modèle et non contrôleur et vue comme ils le disent.
- Comme dit dans la raison 2. si vous voulez séparer la logique du modèle, ce n'est sûrement pas la boîte bleue sur l'image, mais plutôt la boîte en pointillés "Data" (communiquant avec des données réelles bien sûr).
Qt est-il faux dans sa terminologie, ou c'est juste moi qui ne comprends pas? (BTW: La raison pour laquelle ce n'est pas une question académique est que j'ai commencé à coder mon projet en suivant leur nom et j'ai vite découvert que le code n'était clairement pas correct. Ce n'est qu'après cela que j'ai réalisé que je devrais pas essayer de mettre la logique du modèle dans ce qu'ils appellent le modèle)
Réponses:
Je suis d'accord avec vous que la dénomination de Qt est trompeuse. À mon avis cependant, le problème n'est pas seulement celui de Qt, mais il est partagé par tous les cadres qui nous permettent d'adhérer au principe de séparation des préoccupations lors de la mise en œuvre de nos interfaces utilisateur. Quand quelqu'un propose un tel cadre, et trouve un bon moyen de séparer les «choses», il se sent toujours obligé d'avoir des modules qu'ils appellent «Modèle» et d'autres qu'ils appellent «Vue». Au fil des années, j'ai travaillé avec ces frameworks:
Si vous comparez la façon dont les termes «modèle» et «vue» sont utilisés dans ces cadres, et quelles sont les responsabilités des classes dans la «vue», le «modèle» et le «contrôleur» (s'il y en a un), vous trouvent qu'il existe de très grandes différences. Il serait certainement utile d'avoir une comparaison des différents concepts et terminologies, afin que les gens qui passent d'un cadre à un autre aient une chance de rester sains d'esprit, mais cela demanderait beaucoup de travail et de recherche. Une bonne lecture est l' aperçu de Martin Fowler .
Puisqu'il y a tellement d'idées différentes à quoi peut ressembler un modèle MVC, laquelle est correcte? À mon avis, les personnes qui ont inventé MVC devraient être tournées vers qui nous voulons savoir comment il est censé être mis en œuvre «correctement». Dans l'article original de Smalltalk, il est dit:
À la lumière de cela, je répondrais ainsi à vos trois principales préoccupations:
Où nous laisse-t-il? À mon avis, il est préférable de comprendre ce que Qt signifie réellement lorsque les termes «Modèle» et «Vue» sont utilisés et d'utiliser les termes à leur manière pendant que nous programmons avec Qt. Si vous continuez à être dérangé, cela ne fera que vous ralentir, et la façon dont les choses sont configurées dans Qt permet un design élégant - qui pèse plus que leurs «mauvaises» conventions de dénomination.
la source
Réponse courte
Le MVC de Qt ne s'applique qu'à une seule structure de données . Lorsque vous parlez d'une application MVC , vous ne devez pas penser à
QAbstractItemModel
ouQListView
.Si vous voulez une architecture MVC pour tout votre programme, Qt n'a pas un tel framework de modèle / vue "énorme". Mais pour chaque liste / arbre de données de votre programme, vous pouvez utiliser l'approche Qt MVC qui a en effet un contrôleur dans sa vue. Les données se trouvent à l'intérieur ou à l'extérieur du modèle; cela dépend du type de modèle que vous utilisez (propre sous-classe de modèle: probablement dans le modèle; par exemple QSqlTableModel: à l'extérieur (mais peut-être mis en cache dans) le modèle). Pour assembler vos modèles et vos vues, utilisez vos propres classes qui implémentent ensuite la logique métier .
Longue réponse
Approche modèle / vue et terminologie de Qt:
Qt fournit des vues simples pour leurs modèles. Ils ont un contrôleur intégré: la sélection, l'édition et le déplacement des éléments sont ce que, dans la plupart des cas, un contrôleur "contrôle". C'est-à-dire interpréter les entrées de l'utilisateur (clics et mouvements de la souris) et donner les commandes appropriées au modèle.
Les modèles de Qt sont en effet des modèles ayant des données sous-jacentes. Les modèles abstraits ne contiennent bien sûr pas de données, car Qt ne sait pas comment vous voulez les stocker. Mais vous étendez un QAbstractItemModel à vos besoins en ajoutant vos conteneurs de données à la sous-classe et en créant l'interface du modèle pour accéder à vos données. Donc en fait, et je suppose que vous n'aimez pas cela, le problème est que vous devez programmer le modèle, donc comment les données sont accessibles et modifiées dans votre structure de données.
Dans la terminologie MVC, le modèle contient à la fois les données et la logique . Dans Qt, c'est à vous de décider si vous incluez ou non une partie de votre logique métier à l'intérieur de votre modèle ou si vous la mettez à l'extérieur, étant une «vue» en soi. Ce que l'on entend par logique n'est même pas clair: sélectionner, renommer et déplacer des éléments? => déjà implémenté. Faire des calculs avec eux? => Mettez-le à l'extérieur ou à l'intérieur de la sous-classe de modèle. Stocker ou charger des données depuis / vers un fichier? => Mettez-le dans la sous-classe du modèle.
Mon avis personnel:
Il est très difficile de fournir un bon et système MV (C) générique pour un programmeur. Parce que dans la plupart des cas les modèles sont simples (par exemple uniquement des listes de chaînes), Qt fournit également un QStringListModel prêt à l'emploi. Mais si vos données sont plus complexes que des chaînes, c'est à vous de décider comment vous voulez les représenter via l'interface modèle / vue Qt. Si vous avez, par exemple, une structure avec 3 champs (disons des personnes avec nom, âge et sexe), vous pouvez attribuer les 3 champs à 3 colonnes différentes ou à 3 rôles différents. Je n'aime pas les deux approches.
Je pense que le cadre modèle / vue de Qt n'est utile que lorsque vous souhaitez afficher des structures de données simples . Cela devient difficile à gérer si les données sont de types personnalisés ou ne sont pas structurées dans un arbre ou une liste (par exemple un graphique). Dans la plupart des cas, les listes suffisent et même dans certains cas, un modèle ne doit contenir qu'une seule entrée. Surtout si vous souhaitez modéliser une seule entrée ayant différents attributs (une instance d'une classe), le cadre modèle / vue de Qt n'est pas la bonne façon de séparer la logique de l'interface utilisateur.
Pour résumer, je pense que le cadre modèle / vue de Qt est utile si et seulement si vos données sont visualisées par l'un des widgets de visualisation de Qt . C'est totalement inutile si vous êtes sur le point d'écrire votre propre visualiseur pour un modèle ne contenant qu'une seule entrée, par exemple les paramètres de votre application, ou si vos données ne sont pas de types imprimables.
Comment utiliser le modèle / la vue Qt dans une (plus grande) application?
J'ai écrit une fois (en équipe) une application qui utilise plusieurs modèles Qt pour gérer les données. Nous avons décidé de créer un
DataRole
pour contenir les données réelles qui étaient d'un type personnalisé différent pour chaque sous-classe de modèle différente. Nous avons créé une classe de modèle externe appeléeModel
contenant tous les différents modèles Qt. Nous avons également créé une classe de vue externe appeléeView
contenant les fenêtres (widgets) qui sont connectées aux modèles à l'intérieurModel
. Cette approche est donc un Qt MVC étendu, adapté à nos propres besoins. Les deuxModel
etView
classes elles - mêmes n'ont rien à voir avec le MVC Qt.Où avons-nous mis la logique ? Nous avons créé des classes qui ont effectué les calculs réels sur les données en lisant les données des modèles source (lorsqu'ils ont changé) et en écrivant les résultats dans les modèles cibles. Du point de vue de Qt, ces classes logiques seraient des vues, puisqu'elles "se connectent" à des modèles (pas une "vue" pour l'utilisateur, mais une "vue" pour la partie logique métier de l'application).
Où sont les contrôleurs ? Dans la terminologie MVC originale, les contrôleurs interprètent l'entrée utilisateur (souris et clavier) et donnent des commandes au modèle pour exécuter l'action demandée. Étant donné que les vues Qt interprètent déjà les entrées utilisateur telles que le changement de nom et le déplacement d'éléments, cela n'était pas nécessaire. Mais ce dont nous avions besoin, c'était une interprétation de l'interaction utilisateur qui va au-delà des vues Qt.
la source
View
classe, vous devez ajouter le modèle proxy, qui a le modèle d'arbre comme modèle sous-jacent et qui est utilisé par la vue de liste de votre système de fichiers. Comme vous le dites: il ne devrait pas y avoir deux modèles pour les mêmes données. Jamais! (Mais les modèles proxy ne comptent pas comme des modèles séparés.)QAbstractItemModel
, dont certaines sont des modèles au sens de MVC et d'autres non.La terminologie n'est ni bonne ni mauvaise, elle est utile ou inutile.
Vous pouvez changer un peu la question et demander pourquoi Qt n'est pas plus convivial pour MVC. La réponse est que les premiers développeurs de Qt pensent que le découplage de V de C dans les applications GUI entraîne à la fois des V et des C mauvais. La conception de QWidget essaie de simplifier la liaison étroite entre l'interperation d'entrée de la souris et les décisions de sortie des pixels, et vous pouvez voir comment ce n'est pas la voie vers MVC.
la source
Comme la fonction Model est de répondre aux demandes d'informations, je pense qu'il n'y a rien de mal à définir des méthodes telles que
rowCount
,columnCount
etc. Je pense que Model est une sorte de wrapper pour la source de données (peu importe ce que c'est une table SQL ou juste un tableau) , il fournit des données sous forme standard et vous devez définir des méthodes en fonction de la structure de votre source de données.la source
Je pense que leur terminologie est correcte ... bien que dans les applications réelles, je trouve qu'il peut être très facile de brouiller les lignes entre le modèle, la vue et le contrôleur en fonction de votre niveau d'abstraction: la vue d'un niveau peut être le modèle d'un niveau supérieur.
Je sens que la confusion provient de leur classe QAbstractModelItem. Cette classe n'est pas un élément de modèle, mais plutôt une interface vers un modèle. Pour que leurs classes de vue s'interfacent avec le modèle, ils ont dû créer une interface abstraite générique avec le modèle. Cependant, un modèle peut être un seul élément, une liste d'éléments, un tableau de 2 dimensions ou plus d'éléments, etc. leur interface doit donc prendre en charge toutes ces variations de modèle. Certes, cela rend les éléments du modèle assez complexes, et le code de collage pour le faire fonctionner avec un modèle réel semble étirer un peu la métaphore.
la source
Non, leur «modèle» n'est certainement pas un contrôleur.
Le contrôleur est la partie des contrôles visibles par l'utilisateur qui modifient le modèle (et donc modifient indirectement la vue). Par exemple, un bouton «supprimer» fait partie du contrôleur.
Je pense qu'il y a souvent confusion parce que beaucoup voient quelque chose comme "le contrôleur modifie le modèle" et pensent que cela signifie les fonctions de mutation sur leur modèle, comme une méthode "deleteRow ()". Mais dans MVC classique, le contrôleur est spécifiquement la partie de l'interface utilisateur. Les méthodes qui font muter le modèle font simplement partie du modèle.
Depuis que MVC a été inventé, sa distinction entre contrôleur et vue est devenue de plus en plus tendue. Pensez à une zone de texte: elle vous montre à la fois du texte et vous permet de le modifier, alors est-ce une vue ou un contrôleur? La réponse doit être que cela fait partie des deux. À l'époque où vous travailliez sur un télétype dans les années 1960, la distinction était plus claire - pensez-y
ed
- mais cela ne signifie pas que les choses allaient mieux pour l'utilisateur à l'époque!Il est vrai que leur QAbstractItemModel est plutôt de niveau supérieur qu'un modèle ne le serait normalement. Par exemple, les éléments qu'il contient peuvent avoir une couleur d'arrière-plan (un pinceau techniquement), qui est un attribut résolument view-ish! Il y a donc un argument selon lequel QAbstractItemModel ressemble plus à une vue et vos données sont le modèle. La vérité est que c'est quelque part entre les significations classiques de la vue et du modèle. Mais je ne vois pas comment c'est un contrôleur; si quelque chose c'est le widget QT qui l'utilise.
la source