2010-10-27 3 views
9

Ich habe eine Tabelle mit 3000 Zeilen und 8 Spalten. Ich benutze das QTableView. einzufügen Artikel I tun:QTableView ist extrem langsam (sogar für nur 3000 Zeilen)

QStandardItem* vSItem = new QStandardItem(); 
vSItem->setText("Blabla"); 
mModel->setItem(row, column, vSItem); 

wo mmodel QStandardItemModel ist. Alles ist in Ordnung, wenn ich nicht zu viele Zeilen habe, aber wenn ich versuche, große Daten zu visualisieren (etwa 3000 Zeilen), dann ist es extrem langsam (20 Sekunden auf Win 7 64-Bit (8 Kernmaschine mit 8 GB RAM!!!)). Kann ich irgendetwas tun, um die Leistung zu verbessern?

Vielen Dank im Voraus.

Antwort

1

Haben Sie eine Autoresize für Inhalte für Ihre Spalten oder Zeilen? Es kann manchmal ein Killer in der Leistung sein!

Werfen Sie einen Blick hier: QHeaderView::ResizeToContents

Hoffe, es hilft!

+0

nicht explizit. Wenn dies nicht standardmäßig erfolgt, habe ich es nicht. – Tom

+0

Was ich habe, ist: mUi.mImagesTableView-> setAlternatingRowColors (true); mUi.mImagesTableView-> setSelectionMode (QAbstractItemView :: SingleSelection); mUi.mImagesTableView-> setSelectionBehavior (QAbstractItemView :: SelectRows); mUi.mImagesTableView-> setEditTriggers (QAbstractItemView :: NoEditTriggers); mUi.mImagesTableView-> setIconSize (QSize (vIconSize, vIconSize)); mUi.mImagesTableView-> setColumnWidth (0, vIconPlusBorder); mUi.mImagesTableView-> horizontalHeader() -> setStretchLastSection (true); – Tom

+0

probiere und deaktiviere die setStretchLastSection, deaktiviere die automatische Größenanpassung (ich erinnere mich nicht, ob es standardmäßig gemacht wurde) ... Mit anderen Worten, versuche und deaktiviere alles, was mit der Größenanpassung von Zeilen und Spalten zusammenhängen könnte ... In der Version habe ich eine Baumansicht (mit Spalten) mit mehr als 10 Tausend Elemente und ich kann alles ohne Problem Größe ändern ... Aber wenn ich diese Auto-Größenänderung Funktionen einschalten, gehen meine Perfs schlecht! –

3

Ich fand eine Lösung: Das Problem war, dass ich das Modell der Tabellenansicht bereits im Konstruktor zugewiesen. Also jedes Mal, wenn ich das Element in das Modell einfügte, wurde tableview informiert und wahrscheinlich aktualisiert. Jetzt ordnet das Modell der Tabellenansicht erst zu, nachdem ich mein Modell mit Daten gefüllt habe. Dies ist keine elegante Lösung, aber es funktioniert. Gibt es vielleicht eine Möglichkeit, das Modell temporär von zu deaktivieren oder etwas, das zu der Tabellenansicht zu sagt, sich nicht um Änderungen im Modell zu kümmern?

+1

Sie können versuchen, mit blockSignals (http://doc.trolltech.com/main-snapshot/) qobject.html # blockSignals) auf dem Modell, aber das wird Ihnen wahrscheinlich mehr Kopfschmerzen bereiten. Sie sollten wirklich in Betracht ziehen, die Reihenfolge zu ändern oder auf Ihr eigenes Modell umzustellen (damit Sie wissen, wann Sie sagen, dass Sie Daten geändert haben). –

+2

Für große Datenmengen würde ich erwägen, ein "richtiges" Modell zu schreiben, anstatt QStandardItemModel zu verwenden. Dort können Sie Daten in größere Stücke als einzelne Elemente einfügen, wobei jedes die zu aktualisierende Ansicht auslöst, was mich erheblich leistungsfähiger machen sollte. Edit: Ich sehe, ich habe nur wiederholt, was James sagte unten ... –

2

Für diese Datenmenge wäre es besser, wenn Sie ein benutzerdefiniertes Modell verwenden. Dann haben Sie die Kontrolle, wenn Sie beispielsweise die Ansicht von Aktualisierungen informieren. Die "Standard" -Einträge skalieren auf Hunderten und wahrscheinlich Tausenden, da moderne Hardware schnell ist, aber sie sind explizit dokumentiert, da sie nicht für Datensätze dieser Größe gedacht sind.

1

Wenn alle Zeilen die gleiche Höhe haben, kann die Einstellung http://doc.qt.io/qt-5/qtreeview.html#uniformRowHeights-prop auf true die Leistung erhöhen. In meinem Fall war ein Modell, das ungefähr 50.000 Zeilen enthielt, fast unbenutzbar, wobei uniformRowHeights auf false (Standard) gesetzt war. Nachdem es zu wahr geworden ist, hat es wie ein Zauber funktioniert.

+5

Diese Funktion ist für QTreeView, hier reden wir über QTableView –

+0

dabei fast verdoppelt die Geschwindigkeit! – Midhun

6

Guter Aufruf der Autoresize auf Inhalte für Ihre Spalten oder Zeilen.

Ich habe eine Funktion, die der Tabelle jedes Mal eine Spalte hinzufügte, wenn ein Client mit meiner Serveranwendung verbunden wurde. Als die Anzahl der Spalten in der Tabelle groß wurde, schien die Einfügungszeit länger und länger zu dauern.

Ich habe eine ui-> messageLog-> resizeRowsToContents(); jedes Mal. Ich änderte dies, um nur die Größe der Zeile zu ändern, die ui-> messageLog-> resizeRowToContents (0) hinzugefügt wurde, und die Langsamkeit verschwand.

0

Ich verwende 80000 Zeilen und hatte ein ähnliches Problem beim Hinzufügen großer Mengen von Elementen zu einer Tabelle.

Meine Lösung war es, den Speicher im Voraus zuzuteilen, indem Sie ihm sagen, wie viele Zeilen er benötigt.

ich ein QTableView und Modell wurde unter Verwendung, so:

self.model.setRowCount (80000)

Ich bin sicher, dass Sie dies mit Ihrem Code

1

versuchen, dies bieten kann:

   QSqlDatabase db =QSqlDatabase::addDatabase("QSQLITE"); 

     void SELECT_TO_TBLWID(QTableWidget * TBL, QString DbPath,QString SQL) 
        { 
         QSqlDatabase db2 =QSqlDatabase::database(); 
         db2.setDatabaseName(DbPath); 
         if(!db2.open()) 
         { 
         qDebug() << db2.lastError(); 
         qFatal("Failed to connect."); 
         } 
         QSqlQuery qry; 
         qry.prepare(SQL); 
         if(!qry.exec()) 
          qDebug() << qry.lastError(); 
         else 
         { 
          QSqlRecord rec = qry.record(); 

          TBL->setColumnCount(rec.count()); 
          int RW=0; 
          for(int r=0; qry.next(); r++) 
           {RW++;} 
           TBL->setRowCount(RW); 
           for (int pr=RW;qry.previous();pr--){// do nothing} 

         for(int r=0; qry.next(); r++) 
          { 

           for(int c=0; c<rec.count(); c++) 
           { 
            if (r==0) 
            { 
             TBL->setHorizontalHeaderItem(c,new QTableWidgetItem(rec.fieldName(c))); 
            } 

           TBL->setItem(r, c, new QTableWidgetItem(qry.value(c).toString())); 

           } 

          } 
         } 

         db2.close(); 
       } 
+2

Obwohl dieser Code helfen kann, das Problem zu lösen, erklärt er nicht, warum und/oder wie er die Frage beantwortet. Die Bereitstellung dieses zusätzlichen Kontexts würde seinen langfristigen Wert erheblich verbessern. Bitte [bearbeiten] Sie Ihre Antwort, um eine Erläuterung hinzuzufügen, einschließlich der Einschränkungen und Annahmen. –