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

Qt Discussion :

QAbstractItemModel, problème à l'insertion et de drag & drop


Sujet :

Qt

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Par défaut QAbstractItemModel, problème à l'insertion et de drag & drop
    Hello les gens.

    Je bosse sur un éditeur de jeu, et j'ai besoin de préparer un manager d'assets, les assets représentant les fichiers de ressources utilisés par le jeu. (images, sons, ...)

    Je me suis fait une classe d'Asset, qui permet de garder le nom de fichier en mémoire et lui lier quelques options supplémentaires, et un assetManager, proposant d'afficher la listes des assets sous forme d'une QTreeView associé à un AssetModel, dérivé de QAbstractItemModel.

    Le AssetModel contient des AssetProxy, qui sont simplement des liens vers les Assets existant. Un AssetProxy possède un pointeur vers l'Asset auquel il est lié.

    J'ai ajouté une fonction appendRow(AssetProxy *) à mon AssetModel, afin de pouvoir ajouter un nouveau AssetProxy fraichement créé et lié à son Asset.

    Ma classe AssetModel se présente comme ça :
    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
    #pragma once
     
    #include <QAbstractItemModel>
     
    class AssetProxy;
     
    class AssetsModel : public QAbstractItemModel
    {
    	Q_OBJECT
     
    	AssetProxy * m_root;
     
    public:
    	AssetsModel(QObject * parent = 0);
    	~AssetsModel();
     
    	// Reimplemented
    	QVariant data(const QModelIndex &index, int role) const;
    	Qt::ItemFlags flags(const QModelIndex &index) const;
    	QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
    	QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
    	QModelIndex parent(const QModelIndex &index) const;
    	int rowCount(const QModelIndex &parent = QModelIndex()) const;
    	int columnCount(const QModelIndex &parent = QModelIndex()) const;
    	virtual Qt::DropActions supportedDropAction() const;
    	Qt::DropActions supportedDragAction() const;
     
    	bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex());
    	bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex());
    	void changePersistantIndex(const QModelIndex & from, const QModelIndex & to);
    	void changePersistantIndexList(const QModelIndexList & from, const QModelIndexList & to);
     
    	void appendRow(AssetProxy * proxy);
     
    };
    Je vous la mets en entier car je vais y revenir pour un autre problème.

    La fonction appendRow est comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void AssetsModel::appendRow(AssetProxy * proxy)
    {
    	int row = m_root->childCount();
    	beginInsertRows(QModelIndex(), row, row);
    	m_root->appendChild(proxy);
    	endInsertRows();
    }
    Et enfin, voila le résultat :

    Nom : bug.png
Affichages : 123
Taille : 2,2 Ko

    Le but de la fonction appendRow est de mettre les AssetProxy à la suite de la racine de l'arbre, ce qui est fait comme il faut. Là où ça ne va pas, c'est l'embranchement sur le dernier ProxyAsset qui continus comme si un autre Asset était présent à la suite.

    J'aurai besoin que quelqu'un m'explique ce qui ne va pas avec mon code et comment je pourrais faire pour corriger la choses.

    --------------------------------------------------------------------

    La deuxième chose est l'utilisation du Drag & drop. J'aimerais activer le drag & drop pour déplacer les AssetProxy le long de l'arbre.

    J'ai regardé le tutoriel de la doc Qt pour le drag & drop des ItemView. Mes AssetProxy sont draggable, mais pas droppable.

    J'ai configuré ma vue comme ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    m_view = new QTreeView;
    	m_view->setModel(m_model);
    	m_view->header()->setMovable(false);
    	m_view->setSortingEnabled(false);
     
    	// Drag drop options
    	m_view->setSelectionMode(QAbstractItemView::SingleSelection);
    	m_view->setDragDropMode(QAbstractItemView::InternalMove);
    	m_view->setAcceptDrops(true);
    	m_view->setDragEnabled(true);
    	m_view->setDropIndicatorShown(true);
    J'ai aussi surchargé les fonctions supportedDropAction() et supportedDragAction() de mon modèle comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Qt::DropActions AssetsModel::supportedDropAction() const
    {
    	return Qt::MoveAction;
    }
     
    Qt::DropActions AssetsModel::supportedDragAction() const
    {
    	return Qt::MoveAction;
    }
    Ainsi que les flags du model :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Qt::ItemFlags AssetsModel::flags(const QModelIndex &index) const
    {
    	if(index.isValid() && !static_cast<AssetProxy *>(index.internalPointer())->isFolder())
    		return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    	else
    		return Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    }
    Que me manque-t-il pour rendre le drop accepté?

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Par défaut
    Citation Envoyé par Spidyy Voir le message
    Que me manque-t-il pour rendre le drop accepté?
    Le drop est probablement accepté mais il me semble que la treeview ne déplace pas les éléments toute seule suite à un drag-drop, il faut le programmer dans ta fonction dropEvent(). En tout cas c'est que j'ai eu besoin de faire sur un widget perso d'édition d'un arbre de tags avec drag&drop entre les branches:
    http://www.manitou-mail.org/showsour...tagsdialog.cpp

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Par défaut
    J'ai essayé ta solution, mais ça ne résoud pas le problème immédiat. Le truc est que j'obtiens un curseur de type "drop impossible" lorsque je survole ma TreeView.

    Du coup je me demande si il ne faut pas que j'enable les drop pour le widget parent qui contient la treeView ou non.

    EDIT : Bah non, je sèche sur ce coup là. :/

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Par défaut
    Je remarque que ta classe AssetsModel a ces deux méthodes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	virtual Qt::DropActions supportedDropAction() const;
    	Qt::DropActions supportedDragAction() const;
    alors que dans QAbstractItemModel, les noms de ces méthodes ont un S à la fin.
    Du coup ton modèle ne les surcharge pas.
    Peut-être que c'est la raison du problème?

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Par défaut
    Bingo, ça vient de ça...

    Ca, plus un problème due à ma fonction IsFolder() de mes ProxyAssets.

    Je peux droper sur un Asset maintenant. Par contre, je ne peux pas dropper entre deux Asset pour mettre l'objet droppé entre les deux.

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

Discussions similaires

  1. problème d'encoding avec un drag-and-drop.
    Par Luke spywoker dans le forum GTK+ avec Python
    Réponses: 1
    Dernier message: 10/09/2014, 17h24
  2. [Interbase 7] Problème d'insertion de données
    Par Tuscelan dans le forum InterBase
    Réponses: 12
    Dernier message: 19/11/2003, 22h58
  3. STL : std::set problème avec insert ...
    Par Big K. dans le forum MFC
    Réponses: 13
    Dernier message: 08/11/2003, 01h02
  4. Problème d'insertion avec MySQL
    Par Sonny dans le forum ASP
    Réponses: 13
    Dernier message: 28/08/2003, 13h52

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