Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. French
  4. Utilisation des QTreeView
QtWS25 Last Chance

Utilisation des QTreeView

Scheduled Pinned Locked Moved Solved French
3 Posts 3 Posters 1.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    FlaMMe
    wrote on last edited by
    #1

    Bonjour à tous,
    je galère a comprendre comment s'utilise les QTreeView et surtout comment faire le model associé.

    Je vous explique mon projet je souhaite faire une fenêtre qui doit être conçu un comme cette maquette (par soucis de confidentialité j'ai changé totalement mon architecture mais ça reste du même cru):

    alt text

    Je connais assez bien l'utilisation des QTableView, avec leur model et delegate mais c'est la première fois que je m'attaque au QtreeView.

    Je souhaite que les Param 1 et 2 soient modifiables en tant que réel et le param 3 modifiable par le biais d'une combo Box.( donc utilisation d'un delegate j'imagine)

    J’avoue me perdre sur comment créer mon model sachant qu'un "Elément" est propres à son "Etape" et qu'il ne peut pas y avoir de "sousEtape". Mais autant d'étape qu'on veut et autant d'Element par Etape qu'on veut également.

    Ma logique de stockage des données et donc quelque chose comme ça :

    typedef enum sens {HORIZONTAL, VERTICAL}enSens;
    
    typedef struct Element
    {
    	double param1; 
    	double param2; 
    	sens param3;
    }stElement;
    
    typedef struct Etape
    {
    	QString intitule; 
    	QVector<Element> lesElements;
    }stEtape;
    
    class MonModele : public QAbstractItemModel
    {
    	private : 
    		QVector<Etape> mesEtapes;
    		
    	...
    }
    

    Mon problème est le suivant je ne comprend pas comment faire fonctionner ma structure de donnée avec cette histoire de "root.

    par exemple j'ai vu que pour la méthode rowCount par exemple il fallait modifier la valeur en fonction de l'emplacement dans mon architecture( N'hésitez pas a me corrigé si je me trompe).
    Voici en semi pseudo code se que je veux dire :

    int MonModele::rowCount(const QModelIndex &leParent) const
    {
        if ( leParent <correspond a l'etape n> )
    		return mesEtapes[n].lesElements.size();
    	else if (leParent <correspond a l'element root>)
    		return mesEtapes.size();
    	else // si ca correspond a un "Element"
    		return 1;
    }
    
    

    dans mon stockage des données je n'ai pas vraiment de "root" du coup comment savoir si leParent est bien ce "root" en gros comment reconnaître qu'elle est l’élément actif.

    LA methode rowCount n'est qu'un exemple mais en gros comment adapté mon modèle a mon architecture de donnée.
    Je n'ai pas trouvé grand chose comme tutoriel qui n'utilise pas des classes pré-faites comme QStandardItem ou QFileSystemModel, ou alors avec des éléments qui peuvent s'imbriquer a l'infini.
    Pour ma part les Etapes sont restreinte a un premier "niveau" et les "Element" au second niveau.

    Pourriez vous m'indiquer comment faire fonctionner tout cela au mieux?

    Merci d'avance.

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mpergand
      wrote on last edited by mpergand
      #2

      Salut,
      Oui, QTreeView donne mal à la tête :)
      Il faut absolument utiliser un arbre binaire pour les données, comme dans l'exemple: https://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html

      Voici ce que j'utilise comme TreeItemModel:

      TreeItem<DATA>*	rootItem() const { return iTreeItem; }
      
      			TreeItem<DATA>*	itemAtIndex(const QModelIndex& parent) const
      								{
      								const TreeItem<DATA>* item=iTreeItem;
      
      								if(parent.isValid())
      									item=static_cast<TreeItem<DATA>*>(parent.internalPointer());
      
      								return const_cast<TreeItem<DATA>*>(item);
      								}
      
      						int	rowCount(const QModelIndex& parent) const
      								{
      								TreeItem<DATA>* item=itemAtIndex(parent);
      
      								return item->childCount();
      								}
      
      				QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
      								{
      								TreeItem<DATA>* item=itemAtIndex(parent);
      
      								if( (row<0) OR (row>=item->childCount()) )
      									return QModelIndex();
      
      								return createIndex(row,column,item->childAt(row));
      								}
      
      				QModelIndex parent(const QModelIndex& index) const
      								{
      								if (!index.isValid())
      									return QModelIndex();
      
      								TreeItem<DATA>* childItem = static_cast<TreeItem<DATA>*>(index.internalPointer());
      								TreeItem<DATA>* parentItem =childItem->parent();
      
      								if (parentItem->parent() EQ NULL)
      									return QModelIndex();
      
      								int row=parentItem->index();
      								return createIndex(row, 0,(void*)parentItem);
      								}
      
      ...
      private:
      	TreeItem<DATA>*	iTreeItem; // arbre binaire
      

      J'utilise un template pour TreeItem<DATA>, ainsi DATA peut être n'importe quel objet/structure.
      Le TreeItemModel étant générique, j'ai juste à déclarer :

      typedef TreeItem<MaStruct> MonArbreDeDonnées;
      
      class MonTreeModel : public TreeItemModel<MaStruct>
      {
      ...
      }
      

      Bon, je sais c'est pas simple, suis bien example Simple Tree Model, il faut absolument faire comme décrit, commence avec une structure de données simple.
      Good luck ;)

      1 Reply Last reply
      0
      • F Offline
        F Offline
        FlaMMe
        wrote on last edited by FlaMMe
        #3

        Tout d'abord merci d'avoir pris le temps de répondre, et de me montrer un exemple.
        Oui au final c'est ce que j'ai fait.
        J'ai fait un système d'arbre pour mes données.

        enum typeOfNode : char {ROOT,ETAPE,ELEMENT};
        enum Direction :char{ HORIZONTAL,VERTICAL};
        
        
        class Node
        {
            ///----------------------------------
            ///     Attributs
            ///----------------------------------
        protected :
            Node* parent;
        public :
            QVector<Node*> child;
        
            ///----------------------------------
            ///     Methodes
            ///----------------------------------
        public:
            Node(Node* leParent = nullptr);
            virtual ~Node();
            virtual typeOfNode getType()const {return ROOT;}
        
            Node* getParent() {return parent;}
            virtual Node *GetChild(int row);
            int     childCount()const ;
            int row()const ;
        
        };
        
        
        class ElementNode : public Node
        {
            ///----------------------------------
            ///     Attributs
            ///----------------------------------
        public :
            double param1; 
        	double param2;
        	Direction param3;
        
            ///----------------------------------
            ///     Methodes
            ///----------------------------------
        public :
            ElementNode(Node* p_parent=nullptr);
            virtual Node* GetChild(int row){Q_UNUSED(row);return nullptr;}
            virtual typeOfNode getType()const{return ELEMENT;}
        
        };
        
        class EtapeNode : public Node
        {
            ///----------------------------------
            ///     Attributs
            ///----------------------------------
        public :
            QString titre;
            ///----------------------------------
            ///     Methodes
            ///----------------------------------
        public :
            EtapeNode (Node* p_parent =nullptr,QString label = "N.D.");
            virtual typeOfNode getType()const{return ETAPE;}
        };
        
        class TreeModel : public QAbstractItemModel
        {
            ///----------------------------------
            ///     Attributs
            ///----------------------------------
         protected :
            Node* root;
        
            ///----------------------------------
            ///     Methodes
            ///----------------------------------
        public:
            explicit TreeModel(QObject *parent = nullptr);
        
            virtual Qt::ItemFlags flags(const QModelIndex &index) const;
            virtual int rowCount(const QModelIndex & parent) const;
            virtual int columnCount(const QModelIndex&)const;
            virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
            virtual QModelIndex parent(const QModelIndex &child)const;
        
        
            virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
            virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
            virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole);
        
            bool AddEtape(QString Titre);
        	bool AddElement(QModelIndex& etapeParente, QString Titre);
        
        
        
        
        protected :
            QModelIndex IndexForNode(Node *const node)const ;
            Node* NodeForIndex(QModelIndex index)const ;
        };
        

        avec root qui stock les étapes et les étape qui stock les éléments.

        Effectivement les QTreeView donne mal à la tête mais une fois qu'on a compris ça va. Dommage qu'il n'y ai pas plus de tutoriel généraliste sur le sujet.

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved