Bienvenue sur le forum !

Si vous souhaitez rejoindre la communauté, cliquez sur l'un de ces boutons !

Qt 5 : 5.9.1 - Qt Creator : 4.4.0 - Qt Installer : 2.0.3 - JOM : 1.1.2 - Qt Build suite : 1.7.0 - VS Qt 5 : 2.0.0

Bug de QPersistentIndexModel lorsque utilisé avec QTreeWidget ?

Bonjour

QTreeWidget est une classe dérivée de QTreeView qui inclut son propre modèle. Elle permet donc l'affichage mais aussi la gestion du modèle.

Dans QTreeView, l'accès aux éléments se fait par l'intermédiaire de QModelIndex. QTreeWidget, elle, utilise des QTreeWidgetItem... mais comme elle est dérivée, on a encore la possibilité d'accéder via QModelIndex.

Or, j'ai l'impression que ces deux systèmes s'emmêlent les pinceaux. Ou alors, il y a une subtilité que je n'ai pas saisi.

Dans le petit programme qui suit, l'utilisateur sélectionne la ligne qui lui plait et peut la supprimer via la touche Suppr. L'élément suivant est alors automatiquement sélectionné. Si l'élément supprimé était le dernier du dossier, la sélection se fait sur l'élément qui lui précédait. Et si l'élément était le seul du dossier, le parent est alors sélectionné.
Jusque là, rien de compliqué.

main.cpp :
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}
mainwindow.h :
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui>
#include <QtWidgets>

class TreeWidget : public QTreeWidget
{
Q_OBJECT

public:
TreeWidget(QWidget *parent = Q_NULLPTR);

protected:
void keyPressEvent(QKeyEvent *e);
void keyReleaseEvent(QKeyEvent *e);
};

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = 0);
~MainWindow();

protected:

TreeWidget * m_treeWidget;
};

#endif // MAINWINDOW_H
mainwindow.cpp :
#include "mainwindow.h"

#include <QtDebug>

TreeWidget::TreeWidget(QWidget *parent) :
QTreeWidget(parent)
{
setSelectionMode(QAbstractItemView::SingleSelection);
header()->hide();
}

void TreeWidget::keyPressEvent(QKeyEvent *e)
{
if (e->key() == Qt::Key_Delete)
{
QModelIndex currentIdx = currentIndex();
if (!currentIdx.isValid())
return;

int currentRow = currentIdx.row();
QModelIndex currentIdxParent = currentIdx.parent();

int parentRowCount = model()->rowCount(currentIdxParent);

QModelIndex selectIdxParent = currentIdxParent;
int selectRow = currentRow + 1;
if (selectRow >= parentRowCount)
selectRow = parentRowCount - 2;
if (selectRow < 0)
{
selectRow = currentIdxParent.row();
selectIdxParent = currentIdxParent.parent();
}

#if 1 // Ne fonctionne pas correctement !
QPersistentModelIndex selectIdx = model()->index(selectRow, 0, selectIdxParent);
qDebug() << selectIdx.data().toString() << " *** row : " << selectIdx.row() << " *** parent : " << selectIdx.parent().data().toString();
model()->removeRow(currentRow, currentIdxParent);
qDebug() << selectIdx.data().toString() << " *** row : " << selectIdx.row() << " *** parent : " << selectIdx.parent().data().toString();
setCurrentIndex(selectIdx);
#else // Fonctionne
QModelIndex selectIdx = model()->index(selectRow, 0, selectIdxParent);
QTreeWidgetItem * selectIt = itemFromIndex(selectIdx);
model()->removeRow(currentRow, currentIdxParent);
setCurrentItem(selectIt);
#endif
} else
QTreeWidget::keyPressEvent(e);
}

void TreeWidget::keyReleaseEvent(QKeyEvent *e)
{
QTreeWidget::keyReleaseEvent(e);

}

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
m_treeWidget = new TreeWidget;

QTreeWidgetItem * i00 = new QTreeWidgetItem(m_treeWidget);
i00->setText(0, "00");

QTreeWidgetItem * i01 = new QTreeWidgetItem(m_treeWidget);
i01->setText(0, "01");

QTreeWidgetItem * i10 = new QTreeWidgetItem(i01);
i10->setText(0, "10");

QTreeWidgetItem * i11 = new QTreeWidgetItem(i01);
i11->setText(0, "11");

QTreeWidgetItem * i12 = new QTreeWidgetItem(i01);
i12->setText(0, "12");

QTreeWidgetItem * i13 = new QTreeWidgetItem(i01);
i13->setText(0, "13");

QTreeWidgetItem * i20 = new QTreeWidgetItem(i13);
i20->setText(0, "20");

QTreeWidgetItem * i14 = new QTreeWidgetItem(i01);
i14->setText(0, "14");

QTreeWidgetItem * i02 = new QTreeWidgetItem(m_treeWidget);
i02->setText(0, "02");

setCentralWidget(m_treeWidget);
}

MainWindow::~MainWindow()
{

}
Lorsque je stocke un index persistant (qui correspond à l'élément qui sera à sélectionner), je constate que, après que l'élément à supprimer est supprimé, cet index ne se réactualise pas correctement, car il ne correspond plus à l'élément voulu.
Le problème semble se produire à partir du premier niveau de l'arborescence, et non pas à la racine.

Quelqu'un peut-il m'éclairer sur ce dysfonctionnement ?

En utilisant la seconde méthode (setCurrentItem au lieu de setCurrentIndex), le comportement du programme se déroule comme attendu.

Merci pour vos lumières.
Connectez-vous ou Inscrivez-vous pour répondre.