[signal] rowsInserted und rowsAboutToBeInserted

Alles rund um die Programmierung mit Qt
Antworten
forgoden
Beiträge: 120
Registriert: 10. Februar 2008 17:52

[signal] rowsInserted und rowsAboutToBeInserted

Beitrag von forgoden »

Die beiden Funktionen als Signale aus der QAbstractItemModel ergibt sich für mich keinen Sinn.

Warum wird rowsInserted auch vor dem Einfügen der Items aufgerufen? Also noch vor dem Auftauchen der Items im Model wird sie schon aufgerufen. Dadurch stürzt das Programm ab, wenn ich auf Items zugreife, die noch gar nicht existieren. Ich dachte das gehört eher zur Funktion rowsAboutToBeInserted, so wie das Dokument beschreibt?
Win7, VisualStudio 2010, Qt 4.7
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Wie kommst du darauf, dass rowsInserted VOR dem Einfügen emittiert wird? Nur weil dein Programm crasht?
Welches Model verwendest du? Wie fügst du die Items ein? Wie greifst du dann auf die neuen Item zu? Was sagt dein Debugger (->backtrace)?
Solche Fehler liegen fast nie an Qt, sondern am eigenen Programmcode (der verschwindend kleine Rest nennt sich "Bug" und taucht meist nur in recht wenig betretenen Ecken des Funktionsumfangs auf - rowsInserted etc. gehören nicht dazu.)

Also:
Bitte zeig uns deinen Code, an dem wir den Fehler nachvollziehen können. Am besten in Form eines minimalen, kompilierbaren Beispiels.
forgoden
Beiträge: 120
Registriert: 10. Februar 2008 17:52

Beitrag von forgoden »

mainwindows.cpp

Code: Alles auswählen

	model = new QStandardItemModel;
	item = new QStandardItem("Objekte");
	model->setHorizontalHeaderItem(0, item); 

connect( model, SIGNAL( rowsInserted( QModelIndex, int, int ) ), this, SLOT( rowsInserted( QModelIndex, int, int ) ));

Code: Alles auswählen

void MainWindow::rowsInserted( const QModelIndex & parent, int start, int end ) {

	qDebug() << "ctrl pressed" << treeWidget->ctrlkey;
	
	if ((parent.row() == -1) && treeWidget->ctrlkey) {
		for ( ; start <= end; ++start) {
			qDebug() << "[insert] " << model->item(start, 0); // hier stürzt es ab
		}
	}
}
geerbte treeview: (treeWidget ist in Wirklichkeit eine geerbte TreeView)

Code: Alles auswählen

void TreeView::dragMoveEvent(QDragMoveEvent *event) {

	QTreeView::dragMoveEvent(event);

	if ( event->keyboardModifiers() & Qt::ControlModifier)
		ctrlkey=true;
	else ctrlkey=false;

}
Vor kurzem habe ich herausgefunden dass rowsInserted nur funktioniert wenn ich Befehle wie model->appendRow(item); ausführe.

Nicht aber wenn ich MouseDrag die items klone oder verschiebe. In beiden Fällen reagiert rowsInserted spät

Wie ich darauf komme, erfahre ich durch
qDebug() << "[insert] " << model->item(0, 0);
wenn ich diesen Befehl einmal in rowsInserted implementiere und einmal manuell wenn ich Taste G drücke.
Habe ich 2 Items im Model, ziehe ich den ersten nach unten (so dass der 2. Item nach oben kommt) so sehe ich immer noch die Speicheradresse vom ersten item.


Was ist backtrace?
Win7, VisualStudio 2010, Qt 4.7
forgoden
Beiträge: 120
Registriert: 10. Februar 2008 17:52

Beitrag von forgoden »

Abhilfe wäre wenn ich mit
void TreeView::dropEvent(QDropEvent *event);
ein Signal schicke? Ob es dann funkioniert weiss ich nicht. Muss ich noch ausprobieren.
Win7, VisualStudio 2010, Qt 4.7
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Du ignorierst die parents:
http://doc.qt.nokia.com/latest/model-vi ... s-of-items
Da in der Grafik die Angabe zu den rows anschauen!
forgoden
Beiträge: 120
Registriert: 10. Februar 2008 17:52

Beitrag von forgoden »

Okay, wenn ich so schreibe

Code: Alles auswählen

model->index(start, 0, parent).data(ObjectRole);
oder so

Code: Alles auswählen

model->itemFromIndex( model->index(start, 0, parent) )->data(ObjectRole);
in der Funktion rowsInserted schreibe

stürzt es zwar nicht mehr ab, aber die Daten in QVariant bleiben leer. Erst wenn ein zweites Item eingefügt wird, werden die Daten vom ersten Item angezeigt. Das heisst, er greift immer zu früh darauf zu.
Win7, VisualStudio 2010, Qt 4.7
forgoden
Beiträge: 120
Registriert: 10. Februar 2008 17:52

Beitrag von forgoden »

Ich gehe mal davon aus dass irgendwo die Funktion von Qt in DropEvent zuerst die items in Model kopieren lässt, dadurch wird die Funktion rowsInserted aufgerufen. Und dann erst werden die Daten geschrieben.
Win7, VisualStudio 2010, Qt 4.7
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Kannst du bitte deinen Code mal in ein .zip packen und hier anhängen (ALLE Binaries bitte löschen).
Ich bin mir ziemlich sicher, dass du irgendwo einen Fehler einbaust. Ohne dem kompletten für das Problem relevanten Code kann man nicht helfen.
forgoden
Beiträge: 120
Registriert: 10. Februar 2008 17:52

Beitrag von forgoden »

okay hier ist es.

die Klasse object.h ist noch nicht fertig, deswegen einige Merkwürdigkeiten. Hat aber mit dem eigentlichen Problem nichts zu tun denk ich.

Also man fügt einfach Items hinzu mit der Taste "Einfg".
Man klickt auf die Items, um Informationen zu erhalten (debug)

Bei der Ausgabe in der Funktion "rowsInserted" soll int-value als Speicheradresse und den Namen des Items ausgeben. Beim Einfügen macht es keine Probleme damit.

Nur beim schieben und kopieren (mit strg-Taste) von Items zeigt value und Name leer.

Schleifen wie

Code: Alles auswählen

if ((parent.row() == -1) && treeWidget->ctrlkey) {
		for ( ; start <= end; ++start) {
sind natürlich nicht vernünftig - werde ich später weiter ausbauen, sobald das eigentliche Problem behoben ist.

Ich hoffe meine codes sind vollständig. Sind binaries mit exe-Dateien gemeint?
Dateianhänge
objectmanager.zip
(6.04 KiB) 194-mal heruntergeladen
Win7, VisualStudio 2010, Qt 4.7
forgoden
Beiträge: 120
Registriert: 10. Februar 2008 17:52

Beitrag von forgoden »

Konnte einer diesen Fehler reproduzieren?


Ich habe zwar mit dropEvent das Problem gelöst indem ich die Werte (parent, start und end) aus dem Signal rowsInserted zwischenspeichere, daraufhin sendet dropEvent ein Signal aus und eine extra Funktion fixed_rowsInserted wird ausgelöst und übernimmt diese Werte... aber schön ist das Ganze nicht
Win7, VisualStudio 2010, Qt 4.7
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Das schaut mir mittlerweile nach nem Bug her, evtl. in QStandardItemModel. Ich hab den Test etwas ausgeweitet, die Indizes passen nicht. Ich werd mal andere Models ausprobieren und in den Source schauen. Mal gucke...
Antworten