QTableWidget resizeRowsToContents 非常慢
QTableWidget resizeRowsToContents very SLOW
我有一个包含超过 200.000 行和 8 列的 QTableWidget。
列具有固定大小。
行的大小可变。
将项目添加到 table 很快(几秒钟)。
然后resizeRowsToContents() 的调用将近60/120 秒!我看到这个调用是单线程的! (只有一个核心工作)。
我可以强制多线程吗?
如何加快行大小调整?
谢谢,
齐发
Resize需要重新计算,每行的高度和调整。我不建议在单个 QTableWidget 中包含这么多行。我会为这个长列表选择分页技术或一些动态加载功能。
您可能会尝试的一件事是使用 QTableWidget::resizeRowToContents
(注意:Row
而不是 Rows
)逐行更新 QTableWidget
,更新是与队列中的其他事件交错。总体而言,该过程仍将花费相同的时间,但您的 GUI 将在此过程中保持响应。
首先,利用超时为零的 QTimer
将在事件队列变空时发出超时信号这一事实。所以代码如...
QTimer::singleShot(0, &my_callback);
将有效地等到事件队列为空,然后调用 my_callback
。如果 my_callback
调用同一行代码,那么您将拥有一个在下一个空闲期间自动调用自身的函数。
现在写函数...
void resize_row (QTableWidget *view, int row, int count = 1)
{
/*
* Resize rows `row' -> `row + count - 1'
*/
for (int todo = count; row < view->rowCount() && todo--; ++row) {
view->resizeRowToContents(row);
}
/*
* If there are still rows remaining then reschedule.
*/
if (row < view->rowCount()) {
QTimer::singleShot(0, [=](){ resize_row(view, row, count); });
}
}
这将对范围 [行,行 + 计数) 中的所有行调用 view->resizeRowToContents(...)
。如果行索引仍然小于行数,它将使用更新的参数自行安排下一个空闲期。
现在,替换...
table_widget->resizeRowsToContents();
与...
QTimer::singleShot(0, [table_widget, row = 0](){ resize_row(table_widget, row, 10); });
在我完成的基本测试中似乎工作正常。
如果您想要更快的速度,请使用 QAbstractTableModel 而不是 QTableWidget 并覆盖所需的函数。这是一个简单而好的例子:
https://doc.qt.io/qt-5/modelview.html
我有一个包含超过 200.000 行和 8 列的 QTableWidget。 列具有固定大小。 行的大小可变。 将项目添加到 table 很快(几秒钟)。
然后resizeRowsToContents() 的调用将近60/120 秒!我看到这个调用是单线程的! (只有一个核心工作)。 我可以强制多线程吗? 如何加快行大小调整?
谢谢, 齐发
Resize需要重新计算,每行的高度和调整。我不建议在单个 QTableWidget 中包含这么多行。我会为这个长列表选择分页技术或一些动态加载功能。
您可能会尝试的一件事是使用 QTableWidget::resizeRowToContents
(注意:Row
而不是 Rows
)逐行更新 QTableWidget
,更新是与队列中的其他事件交错。总体而言,该过程仍将花费相同的时间,但您的 GUI 将在此过程中保持响应。
首先,利用超时为零的 QTimer
将在事件队列变空时发出超时信号这一事实。所以代码如...
QTimer::singleShot(0, &my_callback);
将有效地等到事件队列为空,然后调用 my_callback
。如果 my_callback
调用同一行代码,那么您将拥有一个在下一个空闲期间自动调用自身的函数。
现在写函数...
void resize_row (QTableWidget *view, int row, int count = 1)
{
/*
* Resize rows `row' -> `row + count - 1'
*/
for (int todo = count; row < view->rowCount() && todo--; ++row) {
view->resizeRowToContents(row);
}
/*
* If there are still rows remaining then reschedule.
*/
if (row < view->rowCount()) {
QTimer::singleShot(0, [=](){ resize_row(view, row, count); });
}
}
这将对范围 [行,行 + 计数) 中的所有行调用 view->resizeRowToContents(...)
。如果行索引仍然小于行数,它将使用更新的参数自行安排下一个空闲期。
现在,替换...
table_widget->resizeRowsToContents();
与...
QTimer::singleShot(0, [table_widget, row = 0](){ resize_row(table_widget, row, 10); });
在我完成的基本测试中似乎工作正常。
如果您想要更快的速度,请使用 QAbstractTableModel 而不是 QTableWidget 并覆盖所需的函数。这是一个简单而好的例子: https://doc.qt.io/qt-5/modelview.html