QTableView非常慢(即使只有3000行)

QTableView非常慢(即使只有3000行),qt,qtableview,Qt,Qtableview,我有一个3000行8列的表格。我使用QTableView。 要插入项目,请执行以下操作: QStandardItem* vSItem = new QStandardItem(); vSItem->setText("Blabla"); mModel->setItem(row, column, vSItem); QSqlDatabase db =QSqlDatabase::addDatabase( "QSQLITE"); void SELECT_

我有一个3000行8列的表格。我使用QTableView。 要插入项目,请执行以下操作:

QStandardItem* vSItem = new QStandardItem();
vSItem->setText("Blabla");
mModel->setItem(row, column, vSItem);
             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();
                 }
其中mModel是QStandardItemModel。 如果我没有太多的行,一切都很好,但是当我试图想象大的时候 数据(大约3000行),然后速度非常慢(在Win7 64位(8核机器,8GB内存!!!)上20秒)。 我能做些什么来提高绩效

             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();
                 }

提前谢谢。

您有自动调整列或行内容大小的功能吗?有时它可能是性能上的杀手

             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();
                 }
请看这里:

             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();
                 }

希望有帮助

我找到了一个解决方案:问题是我将模型分配给了tableview
             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();
                 }
已在构造函数中。所以每次我在模型中插入项目, tableview已通知,可能已更新。现在,我将模型指定给 只有在我用数据填充模型后才能查看tableview。 这不是一个优雅的解决方案,但它是有效的。有没有办法暂时 禁用tableview中的模型或对tableview说要
不关心模型中的更改吗?

对于这种数量的数据,最好使用自定义模型-然后您可以控制何时通知视图更新,例如。由于现代硬件速度快,“标准”项可以扩展到数百个,甚至数千个,但它们被明确记录为不适用于这种大小的数据集。

此外,如果所有行的高度相同,设置为true可以提高性能。在我的例子中,一个包含大约50000行的模型在uniformRowHeights设置为false(默认值)时几乎不可用。将其更改为true后,它就像一个符咒一样工作。

很好地调用了自动调整列或行内容大小的功能

             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();
                 }
我有一个函数,每次客户端连接到我的服务器应用程序时,都会向表中添加一列。随着表中的列数越来越多,插入时间似乎越来越长

             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();
                 }

我在做一个ui->messageLog->resizeRowsToContents();每一次。我将此更改为仅自动调整正在添加的行的大小ui->messageLog->resizeRowToContents(0);,速度变慢了。

我正在使用80000行,在向表中添加大量项时遇到了类似的问题

             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();
                 }
我的解决方案是让它通过告诉它需要多少行来提前分配内存

             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();
                 }
我使用的是Qtableview和模型,因此:

             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();
                 }
self.model.setRowCount(80000)

             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();
                 }

我相信您可以将其与您的代码相匹配

尝试以下方法:

             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();
                 }
QSqlDatabase db=QSqlDatabase::addDatabase(“QSQLITE”);
void SELECT_TO_TBLWID(QTableWidget*TBL、QString DbPath、QString SQL)
{
QSqlDatabase db2=QSqlDatabase::database();
setDatabaseName(DbPath);
如果(!db2.open())
{
qDebug()设置行数(RW);
for(int pr=RW;qry.previous();pr--){//donothing}
for(int r=0;qry.next();r++)
{
对于(int c=0;csetHorizontalHeaderItem(c,新的QTableWidgetItem(rec.fieldName(c)));
}
TBL->setItem(r,c,新的QTableWidgetItem(qry.value(c.toString()));
}
}
}
close();
}

注意SETSECTION RESSIZMEDE()。这对我来说有很大的性能影响。它会导致每一个修改(即每个StEATDATA()/SETTATE())调用的行和列大小重算。直到我达到1000行时,这才是明显的。考虑使用RsisiSeSeX()。相反,这似乎是一次调整。

没有明确说明。除非按照默认设置进行调整,否则我没有它。我有的是:mUi.mImagesTableView->setAlternatingRowColor(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);尝试并禁用setStretchLastSection,禁用自动调整大小(我不记得是否默认完成了)…换句话说,尝试并禁用与调整行和列大小相关的所有内容…在我的应用程序中,在发行版中,我有一个树状视图(带列)有超过10000个项目,我可以毫无问题地调整所有内容的大小…但是如果我打开那些自动调整大小的功能,我的性能会下降得很糟糕!注意:即使在调试中,少量数据也会有性能问题…随机想法:在哪里创建数据?在一个称为“很多时间”的方法中?你可以尝试搞乱在模型上使用BulthSpults(),但这可能会给您带来更大的麻烦。真的,您应该考虑将订单保留相同,或者更改为您自己的模型(这样您就知道何时更改数据)。对于大型数据集,我会考虑写一个“适当的”。模型,而不是使用QStandardItemModel。在那里,你可以插入比单个项目更大的数据块,每个数据块都会触发视图更新,这将使我的性能大大提高。编辑:我看到我刚才重复了James在下面所说的……这个函数是针对QTreeView的,这里我们讨论的是QTableView,这样做的速度几乎是原来的两倍他的代码可能有助于解决问题,但没有解释为什么和/或如何回答问题。提供此附加上下文将显著提高其长期价值。请您的答案添加解释,包括适用的限制和假设。
             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();
                 }