QSortFilterProxyModel, QFileSystemModel & HeapCrash inklusiv

Alles rund um die Programmierung mit Qt
Antworten
tamasi
Beiträge: 45
Registriert: 5. Juli 2007 15:49

QSortFilterProxyModel, QFileSystemModel & HeapCrash inklusiv

Beitrag von tamasi »

Hi fleißige Helfer,

ich habe fogendes Problem.
Aufgrund eines Kundenwunsches sollen Mitarbeiter nur Dateien aus einem ganz bestimmten Verzeichnis auswählen können.
Die Dateien müssen aus mind 1Buchstab+(.dot)+cvs bestehen.
Da der FileDialog das nicht so ganz bewerkstelligt wollte ich den "Umweg" über ein QFileSystemModel , inkl eines QSortFilterProxyModel.

Hier erstmal der Code:

im Klassenkonstruktor

Code: Alles auswählen

//m_fileModel im .h definiert als QFileSystemModel m_fileModel;
O_VERIFY(connect(&m_fileModel,SIGNAL(directoryLoaded(const QString &)),this,SLOT(installFileProxyModel(const QString &))));
	m_fileModel.setFilter(QDir::Files);
	m_fileModel.setRootPath(path);
der angesprungene Slot:
Dialog nur fix provisorisch reingebaut zum testen.

Code: Alles auswählen

void OArticleManagement::installFileProxyModel(const QString & path) {

	//m_fileProxyModel in .h definiert als std::shared_ptr<QSortFilterProxyModel> m_fileProxyModel;
	m_fileProxyModel.reset(new QSortFilterProxyModel(nullptr));
	m_fileProxyModel->setSourceModel(&m_fileModel);
	m_fileProxyModel->setFilterRegExp(QRegExp("^.+\.(?:[cC][sS][vV])$"));//mind 1 Buchstabe und .csv(Groß-Kleinschreibung egal)
	
	m_fileProxyModel->setDynamicSortFilter(true);

        //tree in .h definiert als QTreeView tree
	tree.setModel(m_fileProxyModel.get());
	tree.setSortingEnabled(true);
	tree.setAnimated(false);
	tree.setIndentation(20);

 	tree.setRootIndex(m_fileProxyModel->mapFromSource(m_fileModel.index(path)));

	 tree.header()->setResizeMode(QHeaderView::ResizeToContents);
	
	 mainLayout.addWidget(&tree,0,0);
 	dialog.setLayout(&mainLayout);

 	dialog.exec();

}
Problem a)
Mein Filter scheint so nicht zu funzen(RegExp ist aber richtig, an Online-Testern ausgetestet).
Mit QRegExp ist der Tree leer, ohne sind die Laufwerksbuchstaben drin. In dem Path ist mit 100% Sicherheit eine *.csv Datei drin.

Problem b)

Wenn die Klasse beendet wird, fliegen logischerweise die Member mit raus. Das führt immer zu einem Heap-Fehler. Dort scheinen noch updates gestartet zu werden aber währenddessen fliegt das ganze QTreeWidget weg.
Auszug aus dem Debugger:

Code: Alles auswählen

>	msvcr100d.dll!operator delete(void * pUserData)  Line 52 + 0x51 bytes	C++
 	QtGuid4.dll!QTreeView::`vector deleting destructor'()  + 0x5e bytes	C++
 	QtCored4.dll!QObjectPrivate::deleteChildren()  Line 1935 + 0x24 bytes	C++
 	QtGuid4.dll!QWidget::~QWidget()  Line 1682	C++
 	QtGuid4.dll!QDialog::~QDialog()  Line 329 + 0xf bytes	C++
 	editor_oetikerD.dll!otto::OArticleManagement::~OArticleManagement()  Line 29 + 0x1c bytes	C++
 	

Kann ev wer helfen?
Vielen Dank bereits im Voraus.
nebler
Beiträge: 51
Registriert: 9. Juli 2009 15:26

Re: QSortFilterProxyModel, QFileSystemModel & HeapCrash inkl

Beitrag von nebler »

Zu dem Crash:

Code: Alles auswählen

 m_fileProxyModel->setSourceModel(&m_fileModel);
Ich würde ein Pointer verwenden ... dann übernimmt Qt das löschen des Objektes, wenn es wirklich gelöscht werden soll.

Code: Alles auswählen

/**/
m_fileModel = new FileSystemModel();
/**/
m_fileProxyModel->setSourceModel( m_fileModel );
tamasi
Beiträge: 45
Registriert: 5. Juli 2007 15:49

Re: QSortFilterProxyModel, QFileSystemModel & HeapCrash inkl

Beitrag von tamasi »

Das war wirklich die Lösung für den Heap-Crash.
Danke sehr. Verstehe ich zwar trotzdem nicht so ganz was da schief läuft aber nunja:).

Muss mir da wohl mal genau durchlesen wann Member und wann Pointer gelöscht werden. Scheint so als ob erst die "normalen" Member dran kommen, dann die Pointer.

Problem A konnte ich noch lösen. Habe viel zu kompliziert gedacht.

Proxy weg dafür noch folgende Zeilen zusätzlich im c-tor und fertig :).

Code: Alles auswählen

        O_VERIFY(connect(&m_fileModel,SIGNAL(directoryLoaded(const QString &)),this,SLOT(installFileProxyModel(const QString &))));
	m_fileModel.setFilter(QDir::Files);
	m_fileModel.setRootPath(path);
	m_fileModel.setNameFilters(QStringList() << "*.csv");
	m_fileModel.setNameFilterDisables(false);
Und schwupps, alles wie gewollt.
nebler
Beiträge: 51
Registriert: 9. Juli 2009 15:26

Re: QSortFilterProxyModel, QFileSystemModel & HeapCrash inkl

Beitrag von nebler »

Der Crash dürfte daher kommen.

Wird in Qt ein Objekt gelöscht, so werden automatisch alle Kinder gelöscht.

Code: Alles auswählen

class Foo {
public:
void showModel() {
 _ui->_treeView->setModel( &model ); // Das Model bekommt an der Stelle den Parent '_treeView' zugewiesen.
}

virtual ~Foo() {
 delete _ui;
}

private:
QFileSystemModel _model;
MyUi* _ui;
};
Wird jetzt das Objekt von der Klasse Foo entfernt, so versucht einmal die '_treeView' das Model zu löschen und anschließend noch der Destruktur von der Klasse Foo.
Und zweimal geht nicht ;)
Antworten