Хобрук: Ваш путь к мастерству в программировании

QTableWidget resizeRowsToContents очень МЕДЛЕННО

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

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

Спасибо, Сальво


Ответы:


1

Вы можете попробовать обновить QTableWidget строку за строкой, используя QTableWidget::resizeRowToContents< /a>(Примечание: Row, а не Rows) с обновлениями, чередующимися с другими событиями в очереди. В целом процесс займет столько же времени, но ваш графический интерфейс останется отзывчивым во время процесса.

Во-первых, воспользуйтесь тем фактом, что 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); });

Кажется, работает нормально в основных тестах, которые я сделал.

23.02.2020

2

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

23.02.2020

3

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

23.02.2020
Новые материалы

Библиотеки PyTorch и Python для машинного обучения: приложения в здравоохранении с обнимающим лицом…
В сфере машинного обучения Python выделяется благодаря своей универсальности и набору предлагаемых библиотек. Развитие машинного обучения в здравоохранении можно частично объяснить простотой и..

«Что за…» очень хорошо представляет мое выражение лица после того, как я увидел это!
«Что за…» очень хорошо представляет мое выражение лица после того, как я увидел это!

5 вещей, которые я сделал, чтобы стать профессиональным разработчиком JavaScript
Чтобы стать профессиональным JS-разработчиком: 1. Практикуйтесь в рутине, 2. Работайте над проектами, 3. Придерживайтесь одного языка, 4. Наблюдайте за чужим кодом, 5. Будьте последовательны..

От теории к практике: пошаговое руководство по реализации наивного Байеса
Вы когда-нибудь застревали в проекте классификации, не зная, как точно предсказать результаты для ваших данных? Вы искали более простой и интуитивно понятный алгоритм, который поможет вам достичь..

#093 | Моделирование вспышки эпидемии с помощью JavaScript — Часть 3
TLDR: Я сделал симуляцию вспышки эпидемии, в которую можно поиграть здесь . Мой холст, моя сцена Мой HTML — это всего лишь один div с классом stage, и вот как я настроил на нем свой объект..

numberToString.js (8kyu 16)
Алгоритм кодовых войн Проблема Нам нужна функция, которая может преобразовать число в строку. 숫자를 문자열로 변환하는 함수를 작성해라. Решение 01 function numberToString(n) { return n.toString(); }..

Лучшие практики для быстрого изучения языка программирования
Изучение языка программирования может быть сложной задачей, но при правильном подходе определенно возможно быстро выучить язык программирования. Хорошее понимание языка программирования может..