Seite 1 von 1

Performantes LoggingWidget erstellen

Verfasst: 28. September 2006 10:39
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 ;)

Verfasst: 28. September 2006 11:38
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.

Verfasst: 28. September 2006 11:58
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

Verfasst: 28. September 2006 12:49
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?

Verfasst: 28. September 2006 13:47
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.

Verfasst: 3. Oktober 2006 10:47
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

Verfasst: 3. Oktober 2006 13:11
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.