【问题标题】:How to delete all rows from QTableWidget如何从 QTableWidget 中删除所有行
【发布时间】:2013-03-28 16:54:06
【问题描述】:

我正在尝试从 QTableWidget 中删除所有行。这是我尝试过的。

for ( int i = 0; i < mTestTable->rowCount(); ++i )
{
    mTestTable->removeRow(i);
}

我的桌子上有两行。但这只是删除了一行。一个原因可能是我没有创建具有固定表大小的表。 rowCount() 的 Qt 文档说,

此属性保存表中的行数。

默认情况下,对于没有行数和列数的表, 此属性包含值 0。

如果是这种情况,从表中删除所有行的最佳方法是什么?

【问题讨论】:

  • 您帖子的标题是名词短语,而不是问题。应该是“你好吗”、“一个人怎么样”、“最好的方法是什么”,例如

标签: c++ qt qtablewidget


【解决方案1】:

这对我有用:

for i in reversed(range(self.tableWidget.rowCount())):
    self.tableWidget.removeRow(i)

【讨论】:

    【解决方案2】:

    AFAIK setRowCount(0) 不会删除任何内容。对象仍然存在,但不再可见。

    yourtable->model()->removeRows(0, yourtable->rowCount());
    

    【讨论】:

    • 这与接受的答案相矛盾。哪一个是正确的?
    • 两个都试试。在我使用自定义模型的情况下,我已经这样做了,因为 setRowCount 没有从模型中清除行。我的 Qt 版本是 4.4.x
    • 您不应该使用带有QTableWidget 的自定义模型,内部模型QTableModel 是私有的,并且不是Qt API 的一部分,因此您不能正确地对其进行子类化。而且因为`QTableWidget`在调用每个QTableModel函数之前使用qobject_cast而不检查转换是否成功,如果你的自定义模型没有从QTableModel继承,你会破坏事情。由于QTableWidget::setRowCount 调用QTableModel::setRowCount 确实 调用QTableModel::removeRows 本身删除QTableWidgetItem
    • QTableModel 继承了 QAbstractTableModel ,但以自己的方式实现 QTableModel 是一个可行的选择,例如需要一些功能。我的错,我不确定我是否首先使用了 QTableWidget 和 QTableView。
    【解决方案3】:

    您可以将空项目模型 (QStandardItemModel) 添加到您的 QTableView (myTableView):

    itemModel = new QStandardItemModel;
    ui->myTableView->setModel(itemModel);
    

    【讨论】:

      【解决方案4】:

      删除行的简单方法是将行数设置为零。这在内部使用 removeRows()。

      table->setRowCount(0);
      

      您也可以清除内容,然后删除所有行。

      table->clearContents();
      table->model()->removeRows(0, table->rowCount());
      

      两个 sn-ps 都保持标题不变!

      如果您也需要删除标头,可以从 clearContents() 切换到 clear()

      【讨论】:

      • 第二个函数只在 QTableWidget 中有效,对吗?
      【解决方案5】:

      看这个帖子:http://forum.qt.io/topic/1715/qtablewidget-how-to-delete-a-row

      QList<QTableWidgetItem*> items = table.findItems(.....);
      QMap<int, int> rowsMap;
      for(int i = 0; i < items.count(); i++{
        rowsMap[items.at(i).row()] = -1; //garbage value
      }
      QList<int> rowsList = rowsMap.uniqueKeys();
      qSort(rowsList);
      
      //Now go through your table and delete rows in descending order as content would shift up and hence cannot do it in ascending order with ease.
      for(int i = rowList.count() - 1; i >= 0; i--){
        table.removeRow(rowList.at(i));
      }
      

      【讨论】:

      • 这可以工作..但似乎有很多代码要删除几行:)
      • 这仅适用于删除一组特定的行
      【解决方案6】:

      为了防止应用崩溃,请断开 QTableView 的所有信号。

      // Deselects all selected items
      ui->tableWidget->clearSelection();
      
      // Disconnect all signals from table widget ! important !
      ui->tableWidget->disconnect();
      
      // Remove all items
      ui->tableWidget->clearContents();
      
      // Set row count to 0 (remove rows)
      ui->tableWidget->setRowCount(0);
      

      【讨论】:

        【解决方案7】:

        从视图中删除所有不在标题中的项目。这也将删除所有选择。表格尺寸保持不变。

        void QTableWidget::clearContents()
        

        删除视图中的所有项目。这也将删除所有选择和标题。

        void QTableWidget::clear()
        

        【讨论】:

          【解决方案8】:
          QTableWidget test;
          test.clear();
          test.setRowCount( 0);
          

          【讨论】:

          • 最好在你的答案中添加一些 cmets 或解释代码。
          • 这是最简单的方法。 setRowCount(0) 也 +1
          • 这不会删除任何内容,请参阅下面@damkrat 的答案
          • 这将删除所有内容。也许@damkrat 是对的, setRowCount(0) 什么都不删除,但是 clear() - removes.Clear() 删除所有项目,但表格尺寸保持不变。
          【解决方案9】:

          只需将行数设置为 0:

          mTestTable->setRowCount(0);
          

          它会自动删除QTableWidgetItems,通过调用removeRows,你可以在QTableWidget内部模型代码中看到:

          void QTableModel::setRowCount(int rows)
          {
              int rc = verticalHeaderItems.count();
              if (rows < 0 || rc == rows)
                  return;
              if (rc < rows)
                  insertRows(qMax(rc, 0), rows - rc);
              else
                  removeRows(qMax(rows, 0), rc - rows);
          }
          

          【讨论】:

            【解决方案10】:

            您的代码不会删除最后一行。

            试试这个。

            int totalRow = mTestTable->rowCount();
            for ( int i = 0; i < totalRow ; ++i )
            {
                   mTestTable->removeRow(i);
            }
            

            在您的代码中,rowCount() 第一次具有值2i 的值是0,因此删除1st 行,

            但在第二次i 的值随着1 递增,但rowCount() 返回更新后的行数,现在为1,因此它不会删除最后一行。

            希望你现在清楚了。

            【讨论】:

            • 这似乎不起作用..删除行时索引可能会不断变化..
            • @vinayan - 对不起,你错了。如果考虑总行数为 2,并且在第一次迭代 rowCount() = 2 时,在索引 (i = 0) 0 处删除第一行,在第二次迭代时删除 rowCount() = 1 和索引 @ 987654333@ 1st 所以它尝试在第 1 个索引上删除,但在第 1 个索引行被移动到第 0 个索引,因为第 0 行被删除,所以这里@Vinayan 发布的代码不起作用..
            • 你的逻辑是对的。实际上 rowCount() 并没有按原样给我 2 值,因为 Qt 为没有预定义行的表提供 rowCount() = 0,就像我的案例..感谢您的回答
            • 您的代码不起作用,您不能按该顺序按其索引删除行,因为删除一行会移动其后所有行的索引(i=0 => next要删除的行仍然在 i=0)。如果您必须使用索引,则可以以相反的顺序删除该行,这样删除一个索引不会“使”其他索引“无效”(for ( int i = totalRow-1; i &gt; 0 ; --i ))。
            【解决方案11】:

            我不知道QTableWidget,但您的代码似乎存在逻辑缺陷。您忘记了在循环中您正在减少mTestTable-&gt;rowCount() 的值。删除一行后,i 将为 1,mTestTable-&gt;rowCount() 也将为 1,因此您的循环停止。

            我会这样做

            while (mTestTable->rowCount() > 0)
            {
                mTestTable->removeRow(0);
            }
            

            【讨论】:

            • 这不是一个很好的解决方案,因为它在大数据上可能非常慢。 removeRow(mTestTable-&gt;rowCount()-1) 预计会更快。
            • 这是一个相当糟糕的解决方案,对于具有大量行的QTableWidgets,这将花费大量时间。
            猜你喜欢
            • 2019-06-16
            • 2019-02-06
            • 1970-01-01
            • 2012-03-15
            • 2018-06-08
            • 2020-04-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多