IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PyQt Python Discussion :

Ajouter un élément avec QAbstractListModel [QtGui]


Sujet :

PyQt Python

  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    153
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 153
    Par défaut Ajouter un élément avec QAbstractListModel
    Bonjour,
    Je suis en train d'implémenter un model pour mon listview, voici le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    class ListProjectModel(QAbstractListModel):        
        def __init__(self, datain):
            QAbstractListModel.__init__(self)
            self.projects = datain
        def rowCount(self, parent = QModelIndex()):
            return len(self.projects)
        def data(self, index, role):
            if index.isValid() and role == Qt.DisplayRole:
                return self.projects[index.row()].name
            else:
                return ""
        def setData(self, index, value, role):
            if not index.isValid():
                return False
            elif role != Qt.EditRole:
                return False
            self.projects[index.row()].name = value
            return True
        def flags(self, index):
            return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable
        def insertRows(self, position, rows, parent):
            self.beginInsertRows(QModelIndex(), position, position + rows - 1)
            for row in range(rows):
                self.projects.insert(position, Project(""))
            self.endInsertRows()
            return True
        def removeRows(self, position, rows, parent):
            self.beginRemoveRows(QModelIndex(), position, position + rows -1)
            for row in range(rows):
                self.projects.pop(position)
            self.endRemoveRows()
            return True
    Maintenant quand j'implément un bouton "Add Project" pour pouvoir ajuster un élément dans mon modèle et en même temps mettre à jour ma vue:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        def addProject(self, project):
            self.model.insertRows(self.model.rowCount(), 1, QModelIndex())
            self.model.setData(self.listView.currentIndex(), project.name, Qt.EditRole)
    Je ne vois pas que la vue soit modifiée,
    Quelle est alors la solution pour que la vue et le model sont synchronisés?
    Merci,

  2. #2
    Membre habitué
    Homme Profil pro
    Directeur technique
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Par défaut
    j'ai déjà rencontré un probleme similaire avec un QStandardItemModel affiché dans un QTreeView
    Pour ma part, j'ai simplement eut à reassigner le model à la vue :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    self.treeView = QtGui.QTreeView()
    self.conteneur = QtGui.QStandardItemModel()
    self.treeView.setModel( self.conteneur)
    Et à chaque fois que tu modifies ton model tu réassigne au treeview/listview.

    J'espère que cela aidera

  3. #3
    Membre expérimenté Avatar de ashren
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 101
    Par défaut
    Bonjour,

    ré-implémenter directement QAbstractItemModel est assez complexe.

    Tu as essayé de 'emit' le signal 'dataChanged' dans ta méthode d'insertion ?

  4. #4
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    153
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 153
    Par défaut
    J'ai rajouté cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.emit(SIGNAL("dataChanged(QModelIndex)"), self.projects.index(project))
    Mais cela n'a pas résolu le problème

  5. #5
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    153
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 153
    Par défaut
    Sinon tu peux me fournir un exemple simple sur l'ajout d'un élément d'une liste?
    Merci

  6. #6
    Membre expérimenté Avatar de ashren
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 101
    Par défaut
    Un exemple de comment je vois la chose (au lieu de partir depuis zero) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    from PyQt4.QtGui import QApplication, QWidget, QBoxLayout, QListView, QPushButton, QStandardItem, QStandardItemModel
    from PyQt4.QtCore import Qt
     
    class Project(object):
        pass
     
    class ListProjectModel(QStandardItemModel):        
        def __init__(self):
            QStandardItemModel.__init__(self)
     
        def addProject(self, project):
            item = QStandardItem()
            item.setData(repr(project), Qt.DisplayRole)
            item.setData(project, Qt.UserRole)
            self.appendRow(item)
     
    def addTest(mdl):
        prjtest = Project()
        mdl.addProject(prjtest)
     
    if __name__ == '__main__':
        app = QApplication([])
        win = QWidget()
        win.setLayout(QBoxLayout(QBoxLayout.TopToBottom))
        lst = QListView(win)
        win.layout().addWidget(lst)
     
        mdl = ListProjectModel()
        lst.setModel(mdl)
     
        btnAdd = QPushButton(win)
        win.layout().addWidget(btnAdd)
        btnAdd.clicked.connect(lambda: addTest(mdl))
     
        win.show()
        app.exec_()
    Après, si tu veux vraiment faire un modèle 'from scratch' il faut aller regarder du côté de la documentation/exemples C++ de Qt4.

    Reste à savoir si cette partie de ton programme sera impactée niveau mémoire/cpu si tu part d'un QStandardItemModel, mais là c'est à toi de décider.

  7. #7
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    153
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 153
    Par défaut
    Merci pour tes réponses,
    En fait je sais déjà implémenter un QListWidget, ce que je veux savoir c'est d'implémenter un vrai mécanisme MVC. L'avantage c'est de ne pas dupliquer les objets dans les vues.

    Dans ton exemple, tu as utilisé , pourquoi tu n'utilises pas QAbstractListModel? Et c'est quoi la différence et comment tu fais le choix?
    Merci

  8. #8
    Membre expérimenté Avatar de ashren
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 101
    Par défaut
    J'utilise un QListView, donc MVC (MVD pour être exact).

    Pour le QStandardItemModel (et QStandardItem), ça permet d'avoir un modèle déjà fonctionnel dont ont peut personnaliser les éléments (setData() de QStandardItem). De plus, le modèle est compatible QListView et QTreeView (QTableView aussi je suppose).

    Une implémentation 'from scratch' à partir de QAbstractItemModel est complexe et de mon expérience avec un cas réel (application avec beaucoup d'éléments à afficher sur une machine peu véloce), l'impact sur les performances est négligeable comparé au temps de développement supplémentaire.

    Après, rien de t'empêche d'aller regarder le code source de Qt4 (disponible en version GIT avec visionneuse web) pour savoir comment eux l'ont implémenté (pour te donner une idée).

    Bonne soirée.

  9. #9
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    153
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 153
    Par défaut
    C'est vrai qu'il faut pas trop chercher quand on débute, j'essaie donc de partir de ton idée, merci bien pour les renseignements!

  10. #10
    Membre expérimenté Avatar de ashren
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 101
    Par défaut
    Au contraire, il faut chercher à comprendre.

    Seulement, je trouve qu'il est plus facile de comprendre par l'expérimentation, et surtout en partant de quelque chose de fonctionnel.

    Rien ne t'empêche de partir de code fonctionnel avec un QStandardItemModel, puis quand tout fonctionne, essayer de porter ce modèle vers le QAbstractItemModel.

    Dans tous les cas, bonne journée

  11. #11
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    153
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 153
    Par défaut
    Une autre question, d'après la doc, tu peux donc utiliser QStandardItem pour les ListView, TableView et TreeView?

  12. #12
    Membre expérimenté Avatar de ashren
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 101
    Par défaut
    Les QStandardItem sont les éléments que tu ajoutes au QStandardItemModel, et ce dernier fonctionne avec les QListView et QTreeView (je n'ai pas testé avec QTableView mais ça devrait aussi fonctionner).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 17/06/2011, 17h49
  2. [AC-2003] comment ajouter un élément dans une liste avec InputBox
    Par spacesheep dans le forum VBA Access
    Réponses: 6
    Dernier message: 02/10/2009, 13h33
  3. Ajouter un élément avec 2 listes VB6
    Par alighieri dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 17/04/2008, 16h05
  4. Réponses: 12
    Dernier message: 12/03/2007, 16h58
  5. Réponses: 5
    Dernier message: 12/08/2006, 20h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo