xml - registros - eliminar una tabla en access
QSortFilterProxyModel se bloquea al eliminar una fila del modelo de origen a través de la función de modelo de origen (2)
¿Sabe que los índices de QAbstractItemModel y QSortFilterProxyModel no se pueden mezclar?
Si tiene un QModelIndex de su modelo filterProxy, necesita convertirlo a un QModelIndex a partir del modelo de elemento utilizando QAbstractProxyModel :: mapToSource ().
He creado un modelo QAbstractItemModel-derived personalizado que contiene un conjunto de datos XML en una estructura jerárquica de árbol que se mostrará en un QTreeView como se muestra en esta imagen:
http://imageshack.us/photo/my-images/840/xmltreeview.png
Este modelo ha superado con éxito el ModelTest y algunas pruebas de edición básicas. Sin embargo, me he encontrado con algunos problemas al intentar hacer algunos filtros en este modelo para poder dividir el modelo en algunas vistas diferentes. He intentado QSortFilterProxyModel y se cuelga mucho. Después de algunas reparaciones, aún se bloquea después de intentar eliminar una fila del modelo.
La aplicación de consola muestra estos mensajes cuando se produce un bloqueo:
ratbr QModelIndex (0,0,0xd162000, CGHXmlModel (0xb197e68)) 0 0
rr QModelIndex (0,0,0xd162000, CGHXmlModel (0xb197e68)) 0 0
y esta es la pila de llamadas cuando ocurrió el bloqueo:
0 QSortFilterProxyModelPrivate::index_to_iterator qsortfilterproxymodel.cpp 193 0x0134714b
1 QSortFilterProxyModel::parent qsortfilterproxymodel.cpp 1654 0x0111a677
2 QModelIndex::parent qabstractitemmodel.h 389 0x6a2ad95e
3 QPersistentModelIndex::parent qabstractitemmodel.cpp 347 0x6a1f7320
4 QItemSelectionRange::isValid qitemselectionmodel.h 108 0x01341ea4
5 QItemSelectionModel::isSelected qitemselectionmodel.cpp 1187 0x010f0b58
6 QTreeView::drawRow qtreeview.cpp 1602 0x010db133
7 QTreeView::drawTree qtreeview.cpp 1441 0x010da4f4
8 QTreeView::paintEvent qtreeview.cpp 1274 0x010d9bed
9 QWidget::event qwidget.cpp 8333 0x00c1492d
10 QFrame::event qframe.cpp 557 0x00f8e6bc
11 QAbstractScrollArea::viewportEvent qabstractscrollarea.cpp 1043 0x0101bf0f
12 QAbstractItemView::viewportEvent qabstractitemview.cpp 1619 0x010a5785
13 QTreeView::viewportEvent qtreeview.cpp 1256 0x010d9aa3
14 QAbstractScrollAreaPrivate::viewportEvent qabstractscrollarea_p.h 100 0x01276a13
15 QAbstractScrollAreaFilter::eventFilter qabstractscrollarea_p.h 116 0x0127506c
16 QCoreApplicationPrivate::sendThroughObjectEventFilters qcoreapplication.cpp 847 0x6a1ffc73
17 QApplicationPrivate::notify_helper qapplication.cpp 4392 0x00bc96e5
18 QApplication::notify qapplication.cpp 4361 0x00bc9586
19 QCoreApplication::notifyInternal qcoreapplication.cpp 732 0x6a1ff9dc
20 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 218 0x0123d53e
Todavía soy bastante nuevo en la programación de Qt Model / View y este error realmente ha sido desalentador y me ha dejado rascándome la cabeza durante días. ¡Espero que alguien aquí pueda ayudarme aquí antes de perder todo mi cabello! ¡Gracias!
EDITAR: Actualiza para incluir algunos códigos fuente
Mi proyecto de prueba tiene dos ventanas de diálogo, con un QTreeView cada una. Una es la ventana principal que contiene el miembro de la clase QAbstractItemModel-derived y la otra es una ventana secundaria que contiene el miembro de la clase QSortFilterProxyModel-derived. La ventana secundaria también tiene un puntero QAbstractItemModel para el modelo real.
Ventana principal:
class CGHXMLModelDialog : public QDialog
{
Q_OBJECT
...
private:
Ui::CGHXMLModelDialog *ui;
CGHXmlModel* m_mainModel;
CGHXMLParameterDialog* m_ParamDialog;
...
}
Ventana de niño:
class CGHXMLParameterDialog : public QDialog
{
Q_OBJECT
...
private:
void setupProxyModel();
Ui::CGHXMLParameterDialog* ui;
QAbstractItemModel* m_coreModel;//A CGHXMLModel
CGHXMLSortFilterProxyModel* m_ParamModel;
...
}
En el constructor CGHXMLModelDialog:
m_mainModel = new CGHXmlModel(theDomDocument, this);
ui->CGHXMLTreeView->setModel(m_mainModel);
//Create sub-dialog window containing proxy filter model
m_ParamDialog = new CGHXMLParameterDialog(m_mainModel, this);
que luego llama al método setupProxyModel ():
CGHXMLParameterDialog::CGHXMLParameterDialog(QAbstractItemModel* coreModel, QWidget *parent) :
QDialog(parent),
ui(new Ui::CGHXMLParameterDialog),
m_coreModel(coreModel)
{
ui->setupUi(this);
setupProxyModel();
}
void CGHXMLParameterDialog::setupProxyModel()
{
m_ParamModel = new CGHXMLSortFilterProxyModel(this);
m_ParamModel->setSourceModel(m_coreModel);
m_ParamModel->setFilterRegExp(QRegExp("Parameter"));
m_ParamModel->setFilterKeyColumn(0);
m_ParamModel->setDynamicSortFilter(true);
ui->CGHXMLParamView->setModel(m_ParamModel);
}
He probado insertar filas, editar el contenido de la fila, insertar el atributo XML mediante la edición de columnas (manipulación de columnas personalizadas, no elaboraré), etc. directamente en el modelo fuente y funcionó tanto con como sin el modelo Sort-Filter. El problema ocurre cuando intento eliminar una "fila", que es un elemento XML para mi modelo, cuando hay un modelo Sort-Filter adjunto.
Aquí está mi código para removeRows:
bool CGHXmlModel::removeRows(int rowposition, int rows, const QModelIndex &parent)
{
CGHXMLTreeItem *parentItem = getItem(parent);
bool success = false;
beginRemoveRows(parent, rowposition, rowposition + rows - 1);
success = parentItem->removeChildren(rowposition, rows);
endRemoveRows();
if(success)//Works!
{
emit layoutChanged();
}
return success;
}
que se llama mediante un controlador de eventos de botón en la ventana principal:
void CGHXMLModelDialog::on_deleteRowButton_clicked()
{
QModelIndex currIndex = ui->CGHXMLTreeView->selectionModel()->currentIndex();
if(!m_mainModel->removeRow(currIndex.row(), currIndex.parent()))
{
qDebug() << "Fail to remove row from Model.";
return;
}
}
//Program crashes after this function returns.
Actualización : ¿Es incorrecto emitir layoutChanged () sin emitir layoutAboutToBeChanged ()?
He resuelto este problema comentando la línea "emitir layoutChanged ()" para mis métodos insertRows, removeRows. Originalmente, el código no tenía esta línea, pero un problema de actualización con QTreeView me obligó a incluirlo, sin incluir "emitir layoutAboutToChanged ()". Parece que el problema de actualización ha desaparecido por alguna razón.
De todos modos, gracias a aquellos que intentaron ayudar. Seguramente necesitaré más en el futuro cercano.