QTableWidget resizeRowsToContents очень МЕДЛЕННЫЙ - PullRequest
0 голосов
/ 22 февраля 2020

У меня есть QTableWidget, который содержит более 200 000 строк и 8 столбцов. Столбцы имеют фиксированный размер. Строки имеют переменный размер. Быстрое добавление элементов в таблицу (несколько секунд).

Тогда вызов resizeRowsToContents () занимает почти 60/120 секунд! Я вижу, что этот вызов однопоточный! (Работает только одно ядро). Могу ли я заставить MultiThreading? Как я могу ускорить изменение размера строки?

Спасибо, Salvo

Ответы [ 3 ]

0 голосов
/ 23 февраля 2020

Одна вещь, которую вы можете попробовать, это обновить QTableWidget строка за строкой, используя QTableWidget::resizeRowToContents (Примечание: Row вместо Rows), при этом обновления чередуются с другими событиями в очереди. В целом, процесс все равно займет столько же времени, но ваш 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(...) на всех строках в диапазоне [row, row + count). Если индекс строки все еще меньше, чем число строк, он будет планировать себя на следующий период простоя с обновленными параметрами.

Теперь замените ...

table_widget->resizeRowsToContents();

на ...

QTimer::singleShot(0, [table_widget, row = 0](){ resize_row(table_widget, row, 10); });

Кажется, что он отлично работает в основных тестах, проведенных мной c.

0 голосов
/ 23 февраля 2020

Если вы хотите большей скорости, используйте QAbstractTableModel вместо QTableWidget и переопределите необходимые функции. Это простой и хороший пример: https://doc.qt.io/qt-5/modelview.html

0 голосов
/ 23 февраля 2020

Изменение размера необходимо пересчитать, высоту каждой строки и отрегулировать. Я бы не рекомендовал иметь столько строк в одном QTableWidget. Я хотел бы go для техник нумерации страниц c или некоторых динамических c функций загрузки для этого длинного списка.

...