[resolved] strange thinks around insertRow from QAbstractItemModel customized and QtreeView
-
i have a model/view customized by QAbstractItemModel (works fine) and a inhertited class of QTreeView who promote the QtreeVew.
So: 3 class (separate by files for each): one for items named "Classeur", one for model named "Classeurs_Model" and one for the TreeView named "Classeurs_treeView"The model read/write datas from SQL tables (2 tables, one for content, one for foreign keys linker between other elements objects).
and then, i have a QDialog use the TreeView.
that is the scenario:
the treeView is empty, and i add an item... well, the dialog open, i give data information and accept it... the dialog close, go inside the result condition accepted, insertRow, setData of each column and i can see the item new row inside the view... perfect.
After that, i add an item child... dialog box open, i answer, valide by OK, dialog close, go inside the result condition accepted, insertRow, setData to the child... and... not see it in the tree (but the row has been created).*
Ok.... then i add an other on item (not child) and at the end... i can see the child created before, but without the defined content text ! who is not logical.
From debugger, inside the result part of job back to the accepted dialog retrun, i can see that the QModelIndex of designed new row columns just create one ligne before are invalid ! why ?Also... if i do the job of create the row outside the result condition return from DIalog, no more problem... and i can setData from the inside part of result return from Dialog... this works. But... i don't want that. I really want to insertRow AFTER i accept the text to add to the new rows, and not not AFTER.
also, i not understand why this not works.
here is the part of code for add and add_child slot who not works:
@
void new_project::on_treeView_classeur_add_classeur(QModelIndex index) {
idx_result = index;
QString name_project = ui_new_project->lineEdit_project_name->text();
Classeur *currentClasseur = classeurs_model->getClasseur(index);
add_classeur_files *dialog_add_classeur;
dialog_add_classeur = new add_classeur_files(this, name_project, classeurs_model, currentClasseur);
dialog_add_classeur->open();
QObject::connect(dialog_add_classeur, &QDialog::finished,
[dialog_add_classeur, this](int result){
if(result) {
if(!classeurs_model->insertRows(idx_result.row()+1, 1, idx_result.parent()))
return;
QModelIndex idxClasseurName = classeurs_model->index(idx_result.row()+1, 0,
idx_result.parent());
QModelIndex idxClasseurComment = classeurs_model->index(idx_result.row()+1, 1,
idx_result.parent());
QModelIndex idxClasseuridP = classeurs_model->index(idx_result.row()+1, 3,
idx_result.parent());
QModelIndex oldIdxAtidP = classeurs_model->index(idx_result.row(), 3,
idx_result.parent());
classeurs_model->setData(idxClasseurName,
dialog_add_classeur->New_classeur.name, Qt::EditRole);
classeurs_model->setData(idxClasseurComment,
dialog_add_classeur->New_classeur.comment, Qt::EditRole);
if(idx_result.parent().isValid())
classeurs_model->setData(idxClasseuridP, oldIdxAtidP.data(), Qt::EditRole);
else
classeurs_model->setData(idxClasseuridP, QVariant(0), Qt::EditRole); }
dialog_add_classeur->deleteLater(); });
}void new_project::on_treeView_classeur_add_child_classeur(QModelIndex index) {
idx_result = index;
QString name_project = ui_new_project->lineEdit_project_name->text();
Classeur *currentClasseur = classeurs_model->getClasseur(index);
add_classeur_files *dialog_add_classeur;
dialog_add_classeur = new add_classeur_files(this, name_project, classeurs_model, currentClasseur);
dialog_add_classeur->open();
QObject::connect(dialog_add_classeur, &QDialog::finished,
[dialog_add_classeur, this](int result){
if(result) {
if(!classeurs_model->insertRows(0, 1, idx_result))
return;
QModelIndex idxClasseurName = classeurs_model->index(0, 0, idx_result);
classeurs_model->setData(idxClasseurName,
dialog_add_classeur->New_classeur.name, Qt::EditRole);
QModelIndex idxClasseurComment = classeurs_model->index(0, 1, idx_result);
classeurs_model->setData(idxClasseurComment,
dialog_add_classeur->New_classeur.comment, Qt::EditRole);
QModelIndex idxClasseurIdP = classeurs_model->index(0, 3, idx_result);
QModelIndex oldParentAtId = classeurs_model->index(idx_result.row(), 2,
idx_result.parent());
classeurs_model->setData(idxClasseurIdP, oldParentAtId.data(), Qt::EditRole); }
dialog_add_classeur->deleteLater(); });
}
@ -
and this is one works (nut i don't want to inserRow before answer the dialog box for text coluimn 0 and 1):
@
void new_project::on_treeView_classeur_add_classeur(QModelIndex index) {
idx_result = index;
QString name_project = ui_new_project->lineEdit_project_name->text();
Classeur *currentClasseur = classeurs_model->getClasseur(index);
if(!classeurs_model->insertRows(index.row()+1, 1, index.parent()))
return;
QModelIndex idxClasseuridP = classeurs_model->index(index.row()+1, 3,
index.parent());
QModelIndex oldIdxAtidP = classeurs_model->index(index.row(), 3,
index.parent());
if(index.parent().isValid())
classeurs_model->setData(idxClasseuridP, oldIdxAtidP.data(), Qt::EditRole);
else
classeurs_model->setData(idxClasseuridP, QVariant(0), Qt::EditRole);
add_classeur_files *dialog_add_classeur;
dialog_add_classeur = new add_classeur_files(this, name_project, classeurs_model, currentClasseur);
dialog_add_classeur->open();
QObject::connect(dialog_add_classeur, &QDialog::finished,
[dialog_add_classeur, this](int result){
if(result) {
QModelIndex idxClasseurName = classeurs_model->index(idx_result.row()+1, 0,
idx_result.parent());
QModelIndex idxClasseurComment = classeurs_model->index(idx_result.row()+1, 1,
idx_result.parent());
classeurs_model->setData(idxClasseurName,
dialog_add_classeur->New_classeur.name, Qt::EditRole);
classeurs_model->setData(idxClasseurComment,
dialog_add_classeur->New_classeur.comment, Qt::EditRole); }
dialog_add_classeur->deleteLater(); });
}void new_project::on_treeView_classeur_add_child_classeur(QModelIndex index) {
idx_result = index;
QString name_project = ui_new_project->lineEdit_project_name->text();
Classeur *currentClasseur = classeurs_model->getClasseur(index);
if(!classeurs_model->insertRows(0, 1, index))
return;
for (int column = 0; column < classeurs_model->columnCount(index.parent()); ++column) {
QModelIndex newClasseur = classeurs_model->index(0, column, index);
if(column == 3) {
QModelIndex oldAtColumn = classeurs_model->index(index.row(), column - 1, index.parent());
classeurs_model->setData(newClasseur, oldAtColumn.data(), Qt::EditRole); } }
add_classeur_files *dialog_add_classeur;
dialog_add_classeur = new add_classeur_files(this, name_project, classeurs_model, currentClasseur);
dialog_add_classeur->open();
QObject::connect(dialog_add_classeur, &QDialog::finished,
[dialog_add_classeur, this](int result){
if(result) {
QModelIndex idxClasseurName = classeurs_model->index(0, 0, idx_result);
QModelIndex idxClasseurComment = classeurs_model->index(0, 1, idx_result);
classeurs_model->setData(idxClasseurName,
dialog_add_classeur->New_classeur.name, Qt::EditRole);
classeurs_model->setData(idxClasseurComment,
dialog_add_classeur->New_classeur.comment, Qt::EditRole); }
dialog_add_classeur->deleteLater(); });
}
@thanks to tell me what i can do for make it do the correct job and show new item child with datas cloumn 0 and 1 correctly edited.
-
I added ui_new_project->treeView_Classeurs->update() just after insertRows() method, but this resolve ONLY if i use the debugger (with the debugger, every thing works perfectly). If i compil and use without the debugger, nothing works fine, the child is create without the setData text for the first child create, but the second child create setData well... really strange, looks like a bug.
Is it a BUG ?
How is it possible to have something works fine ? -
OK !
I resolve, it was an error of wrong call of the QDialog:
If i open() the dialog box BEFORE connect it... this will be a problem for the memory links.
For resolve, just put the "dialog_add_classeur->open();" AFTER QObject::connect.... and NOT BEFORE.this resolve all the strange problems.