Modèle et QTabWidget

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour,

J'utilise PyQt pour une app permettant de créer des cartes. Une carte, ici, c'est quelques options et un verger :

  • Map
    • Some options
    • Orchard
      • Row
        • Side
          • VArea
            • HArea

Le verger s'intègre très bien dans une QTreeView donc j'utilise un modèle héritant de QAbstractItemModel pour le représenter.

Je souhaiterais que ma QMainWindow s'organise ainsi :

  • Menu
  • Dock widget : options de la carte courante (QWidget)
  • Dock widget : verger de la carte courante (QTreeView)
  • Central widget : onglets des cartes (QTabWidget)
    • chaque onglet contiendrait une QGraphicsView qui permettrait de représenter le verger de la carte courante (en plus de la QTreeView)
  • Status bar

Quand on ouvrirait un onglet, le modèle du verger associé serait passé à la QTreeView et à la QGraphicsView et le widget des options serait rempli à partir des attributs de l'objet Map - a priori, pas besoin de modèle vu qu'on ne partage pas les données (?).

Du coup, je me demandais comment gérer ça. Est-ce que, dans ma QMainWindow j'utilise un simple tableau dans lequel je vais chercher la carte correspondante lors d'un changement d'onglet ?

Ou alors je crée un modèle englobant tout - donc commençant au niveau "Map" - et j'implémente ma propre vue globale (QTabWidget + QTreeView + QGraphicsView + QWidget). Le souci, c'est que je souhaitais placer certain composants dans des docks.

Merci. =)

Édité par Vayel

+0 -0
Auteur du sujet

Pour ceux que ça intéresse, j'ai pour l'instant opté pour ça :

  • QMainWindow
    • _mapModel = modèle héritant de QAbstractModel : contient les cartes
      • Map
        • Méthodes et attributs
        • _model = modèle héritant de QAbstractModel : contient le verger
    • _mapTabWidget = QTabWidget

Création :

  • Création d'un objet Map, contenant un modèle pour le verger
  • Création d'une page dans le QTabWidget
  • Stockage de l'objet Map via QTabWidget.tabBar().setTabData

Sélection :

  • Changement de page
    • Récupération de la sélection courante dans la page courante
    • Émission d'un signal avec l'index courant
  • Changement d'index dans la page courante
    • Émission d'un signal avec l'index courant

Suppression :

  • Récupération de la page courante
    • Récupération de l'index courant
    • Récupération du modèle où se situe l'index via QTabWidget.tabBar().tabData().model()
    • Suppression de l'index

Vous remarquerez que _mapModel ne m'est pas utile. Je préfère toutefois le garder si jamais j'implémentais une vue personnalisée au lieu d'un QTabWidget.

Édité par Vayel

+0 -0

Quelques remarques peu objectives : je n'aurais pas stocké les modèles et les vues directement mais je serais passé par un composant englobant modèle et vue. De cette manière, je gagne en flexibilité si je veux changer et ça évite de tout mettre dans la mainwindow.

Si possible, je n'aurais pas utiliser de QGraphicsView mais une vue perso pour garder le pattern MVC jusqu'au bout et aussi simplifier un peu tout ça (Qt s'occupe de tout). Si ce n'est pas possible, j'aurais Alor créer une nouvelle classe fille de QGraphicsScene qui serait venu se calquer sur mon modèle. De cette manière, je laisse ma graphicsview se mettre à jour avec le modèle et j'évite d'envoyer moi-même les ordres.

J'aurais aussi remplacer le QTabWidget par une vue, étant donné qu'il doit interagir avec le modèle (et vu que c'est son seul objectif), histoire d'éviter tout problème d'index stocké pas à jour.

Bon, ça demande une quantité énorme de boulot supplémentaire pour finalement, pas grand chose de plus. Mais ça aurait l'avantage d'être plus cohérent (tout ce qui utilise le modèle est une vue du modèle et doit donc être prévenu du moindre changement).

Shave the whales! | Thistle

+0 -0
Auteur du sujet

Merci pour ce retour. =)

Tu veux dire que tu aurais créé un objet avec deux attributs et que c'est cet objet que tu aurais passé en argument aux objets Map ? En fin de compte, je n'ai que deux sortes de modèles : un pour stocker les cartes - une liste - et un, dans chaque carte, pour stocker le verger - un arbre. Du coup, chaque carte est obligée d'avoir une instance du modèle pour stocker son verger, non ?

J'aurais alors un truc comme ça :

  • MainWindow
    • _mapModel
      • Map
        • Attributs et méthodes
        • (_orchardModel, _orchardView) - ou un objet ici.

A mes onglets, je passerais le _mapModel en argument et à chaque carte sélectionnée via les onglets, j'afficherais _orchardView avec le modèle _orchardModel.

Pour ce qui est des vues personnalisées, c'est ce que je comptais faire, mais j'ignore un peu comment - je n'ai déniché que ça. Vu que le résultat graphique est similaire à un(e) QTabWidget/ QGraphicsView, faut-il que je me base sur ces classes ?

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte