Performantes LoggingWidget erstellen

Alles rund um die Programmierung mit Qt
Antworten
Delryn
Beiträge: 70
Registriert: 24. Februar 2006 11:15

Performantes LoggingWidget erstellen

Beitrag von Delryn »

Hallo!

Ich versuche seit 2 Tagen ein schnelles LoggingWidget zu erstellen.
Ich hatte zuerst ein QDockWidget mit einem QTextEdit. Sobald der String im QTextEdit aber zu groß wurde hat es so dermaßen geruckelt, vor allem beim ändern der Größe, dass das nicht brauchbar war.

Jetzt habe ich mich informiert und ein QListWidget genommen.

Bei so ca. 4500 Einträgen geht aber auch das in die Knie.
Gibt es in Qt nichts vernünftiges zum Loggen? Das kann doch nicht sein?

Die Anforderungen sind halt so ca 10.000 bis 30.000 Zeilen Text Pro Minute.

Falls jemand eine Idee hat -> her damit ;)
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Das sind aber ganz schön viel Einträge - die kann doch eh keiner lesen... also lass das widget nur alle paar zehntelsekunden komplett neuzeichnen -> setUpdatesEnabled(), am besten mit einem QTimer oder so.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Delryn
Beiträge: 70
Registriert: 24. Februar 2006 11:15

Beitrag von Delryn »

Christian81 hat geschrieben:Das sind aber ganz schön viel Einträge - die kann doch eh keiner lesen... also lass das widget nur alle paar zehntelsekunden komplett neuzeichnen -> setUpdatesEnabled(), am besten mit einem QTimer oder so.
Okay, wird versucht.
Ich denke übrigens auch das das zuviele Informationen sind, aber es wird so gewünscht.
Melde mich dann nochmal
Delryn
Beiträge: 70
Registriert: 24. Februar 2006 11:15

Beitrag von Delryn »

Also das bringt schonmal einen spürbaren Performancegewinn.
Ich deaktiviere das neuzeichnen, füge alle neuen Items an und aktiviere es wieder.

Trotzdem verkraftet es noch recht wenig Einträge.
Ich habe das untersucht und es liegt definitiv an der

Code: Alles auswählen

m_pQListWidget->addItem();

Hier der mein Code zum anhängen:

Code: Alles auswählen

// ----------------------------------------------------------------------------
void CLoggingWindow::TransmitMessage(QList<QListWidgetItem*> qlist)            
// ----------------------------------------------------------------------------
{
    setUpdatesEnabled(false);

    
	if(m_pQListWidget->count() > 1000) // Meine Notlösung
	{
		pQListWidget->clear();
	}

	while (!qlist.isEmpty())
	{
		m_pQListWidget->addItem( qlist.takeFirst() );	
	}


	//	m_pQListWidget->scrollToBottom(); is buggy and does not work
	m_pQListWidget->scrollToItem( m_pQListWidget->item( m_pQListWidget->count() -1 ) ); 

	setUpdatesEnabled(true);
}

Wenn man addItem jetzt mal auskommentiert und nur die Liste Element für Element leert, verbraucht meine Anwendung nur noch 5% CPU-Rechenpower:

Code: Alles auswählen

	while (!qlist.isEmpty())
	{
		qlist.takeFirst();
		//m_pQListWidget->addItem( qlist.takeFirst() );	
	}
Hättest du noch eine Idee, wie man mehrere Einträge schnell anhängen könnte?



Edit:
Ich sehe, dass man eine QStringList übergeben kann. Das wäre aber suboptimal, da ich gerne die Loggingprioritäten unterscheiden möchte.

Momentan sieht das nämlich so aus:

http://img147.imageshack.us/my.php?imag ... nntlb5.png
Bild

D.h. ich brauch Items mit Icon...
muss ich in den Sauren Apfel beißen?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

So auf die Schnelle hätte ich keine Idee. Nur list.takeFirst() ist u.U. eine Performancebremse. Da ist es besser die Liste durchzulaufen und dann alles auf einmal zu löschen da ansonsten immer alles innerhalb der Liste rumgeschoben werden muss.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
DarkWotan
Beiträge: 65
Registriert: 18. Mai 2006 10:03

Beitrag von DarkWotan »

Meine Vermutung ist, auf den Erfahrungen eines Kumpels von mir basierend, dass addItem() lediglich Speicher für das gerade hinzuzufügende Element reserviert. Sehr oft aufgerufen erzeugt das viel Last beim Betriebssystem, ständig so kleine Blöcke Speicher anzufordern.
Ein Lösungsvorschlag, den ich allerdings nicht getestet habe, wäre, dass du das ganze auf MVC umstellst, und mit beginInsertRows(), insertRows() und endInsertRows() arbeitest, siehe http://doc.trolltech.com/4.1/qabstractl ... ubclassing

MfG, Cedric
tachyon
Beiträge: 29
Registriert: 22. Juli 2006 10:03

Beitrag von tachyon »

Bau doch eine zusätzliche Datenstruktur im Hintergrund auf, die das Log enthält, und zeige im Listenfeld nur das an, was tatsächlich reinpasst. Das heisst, solange neuer Text reintrudelt z.B. immer die letzten 10 Zeilen, ansonsten den Pufferinhalt abhängig von der Rollbalkenposition. Die Datenstruktur könnte z.B. ein log-File sein.
Antworten