Nano Hash - криптовалюты, майнинг, программирование

Проблемы с производительностью со многими виджетами, соответственно сложенными QTableWidgets

Мне нужно отобразить сложную таблицу, и я решил использовать сложенные QTableWidgets. С увеличением количества строк программе требуется много времени для создания всех виджетов и почти столько же времени для отображения.

Основная таблица выглядит так: MainTable

Составной TableWidget в таблице:

StackedTables

если ячейка содержит данные, в одной ячейке MainTable есть хотя бы один TableWidget, а в худшем случае в этой ячейке есть еще 2 TableWidget. Это означает, что у меня может быть 3 TableWidgets в одной ячейке.

Измерение времени с помощью cProfile и time.time для 80 строк (с 48 сложными ячейками для каждой строки):

complete update time: 15s (manually stopped)
time to create the table: 7.548534870147705s (time.time over complete function)
display time: 7.5s (complete update time - function time)
rows: 80

     63600 function calls in 7.462 seconds

   Ordered by: internal time

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
 1896    2.455    0.001    3.882    0.002     DigitalePlanungstafel.py:6054(grundWidgetErstellen) -- (create table in cell)
 3936    2.027    0.001    2.027    0.001 {built-in method setCellWidget}
 2535    1.306    0.001    1.306    0.001 {built-in method setColumnCount}
  630    0.770    0.001    1.183    0.002 DigitalePlanungstafel.py:6035(obenWidgetErstellen) -- (create table in table in cell)
 2607    0.674    0.000    0.674    0.000 {built-in method setRowCount}
 2528    0.059    0.000    0.059    0.000 {built-in method horizontalHeader}
 2526    0.021    0.000    0.021    0.000 {built-in method verticalHeader}
  163    0.019    0.000    0.019    0.000 {method 'execute' of 'sqlite3.Cursor' objects}
 2526    0.016    0.000    0.016    0.000 {built-in method setFrameShape}
 1410    0.014    0.000    0.014    0.000 {built-in method setStyleSheet}
 4502    0.013    0.000    0.013    0.000 {built-in method setRowHeight}
 2526    0.009    0.000    0.009    0.000 {built-in method setFixedSize}
 2546    0.009    0.000    0.009    0.000 {built-in method setColumnWidth}
 5052    0.009    0.000    0.009    0.000 {built-in method setVisible}
 1329    0.007    0.000    0.007    0.000 {built-in method setItem}
 2181    0.006    0.000    0.006    0.000 {built-in method cellWidget}
   80    0.005    0.000    0.005    0.000 {built-in method addWidget}
 2526    0.004    0.000    0.004    0.000 {built-in method setEditTriggers}
  929    0.004    0.000    0.004    0.000 {built-in method setBackground}
 1330    0.003    0.000    0.003    0.000 {method 'format' of 'str' objects}
  414    0.003    0.000    0.003    0.000 {built-in method _pickle.loads}
  336    0.003    0.000    0.003    0.000 {method 'strftime' of 'datetime.date' objects}
 2526    0.003    0.000    0.003    0.000 {built-in method setHorizontalScrollBarPolicy}
 1410    0.002    0.000    0.002    0.000 {built-in method setFixedHeight}
 1377    0.002    0.000    0.002    0.000 {built-in method setTextAlignment}
   83    0.002    0.000    0.004    0.000 _strptime.py:321(_strptime)
    2    0.002    0.001    0.002    0.001 {built-in method setSortingEnabled}
 2526    0.001    0.000    0.001    0.000 {built-in method setShowGrid}
 1570    0.001    0.000    0.001    0.000 {built-in method rowHeight}
 2526    0.001    0.000    0.001    0.000 {built-in method setSelectionMode}
  163    0.001    0.000    0.001    0.000 {method 'fetchall' of 'sqlite3.Cursor' objects}
  240    0.001    0.000    0.001    0.000 DigitalePlanungstafel.py:7494(__init__)
 2526    0.001    0.000    0.001    0.000 {built-in method setVerticalScrollBarPolicy}
    1    0.001    0.001    0.001    0.001 {built-in method sortByColumn}
   80    0.001    0.000    0.001    0.000 {built-in method setLayout}
   83    0.001    0.000    0.001    0.000 {built-in method _locale.setlocale}
    1    0.001    0.001    0.001    0.001 {built-in method _sqlite3.connect}
   89    0.000    0.000    0.000    0.000 {built-in method setForeground}
   83    0.000    0.000    0.000    0.000 {method 'match' of '_sre.SRE_Pattern' objects}
   83    0.000    0.000    0.004    0.000 _strptime.py:562(_strptime_datetime)
   48    0.000    0.000    0.000    0.000 {built-in method setHorizontalHeaderItem}
   80    0.000    0.000    0.000    0.000 {built-in method setContentsMargins}
   83    0.000    0.000    0.005    0.000 {built-in method strptime}
   83    0.000    0.000    0.000    0.000 locale.py:379(normalize)
   88    0.000    0.000    0.000    0.000 {built-in method setFont}
  160    0.000    0.000    0.000    0.000 {built-in method setData}
   83    0.000    0.000    0.000    0.000 {method 'groupdict' of '_sre.SRE_Match' objects}
   80    0.000    0.000    0.000    0.000 {built-in method setAlignment}
   83    0.000    0.000    0.001    0.000 _strptime.py:29(_getlang)
   83    0.000    0.000    0.001    0.000 locale.py:565(getlocale)
   83    0.000    0.000    0.001    0.000 locale.py:462(_parse_localename)
   80    0.000    0.000    0.000    0.000 {built-in method setUnderline}
    1    0.000    0.000    0.000    0.000 {built-in method io.open}
  249    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}
    1    0.000    0.000    0.000    0.000 {method 'close' of 'sqlite3.Connection' objects}
  160    0.000    0.000    0.000    0.000 {built-in method item}
  742    0.000    0.000    0.000    0.000 DigitalePlanungstafel.py:7499(__lt__)
   48    0.000    0.000    0.000    0.000 {built-in method today}
  165    0.000    0.000    0.000    0.000 {method 'toordinal' of 'datetime.date' objects}
  475    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
  167    0.000    0.000    0.000    0.000 {built-in method builtins.len}
  166    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}
   83    0.000    0.000    0.000    0.000 {method 'end' of '_sre.SRE_Match' objects}
   84    0.000    0.000    0.000    0.000 {method 'lower' of 'str' objects}
    1    0.000    0.000    0.000    0.000 {method 'close' of '_io.TextIOWrapper' objects}
    2    0.000    0.000    0.000    0.000 {built-in method builtins.print}
   83    0.000    0.000    0.000    0.000 {method 'keys' of 'dict' objects}
   47    0.000    0.000    0.000    0.000 {built-in method columnCount}
   83    0.000    0.000    0.000    0.000 {method 'weekday' of 'datetime.date' objects}
   96    0.000    0.000    0.000    0.000 {method 'date' of 'datetime.datetime' objects}
   20    0.000    0.000    0.000    0.000 {built-in method columnWidth}
    1    0.000    0.000    0.000    0.000 {built-in method _locale._getdefaultlocale}
    3    0.000    0.000    0.000    0.000 {method 'split' of 'str' objects}
    1    0.000    0.000    0.000    0.000 _strptime.py:284(_calc_julian_from_U_or_W)
    1    0.000    0.000    0.000    0.000 _bootlocale.py:11(getpreferredencoding)
    1    0.000    0.000    0.000    0.000 {built-in method sortIndicatorOrder}
    2    0.000    0.000    0.000    0.000 {built-in method time.time}
    1    0.000    0.000    0.000    0.000 {method 'cursor' of 'sqlite3.Connection' objects}
    2    0.000    0.000    0.000    0.000 {method 'index' of 'list' objects}
    1    0.000    0.000    0.000    0.000 {built-in method fromordinal}
    1    0.000    0.000    0.000    0.000 {built-in method sortIndicatorSection}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    1    0.000    0.000    0.000    0.000 codecs.py:259(__init__)

Время для вызова функции и создания таблицы нормальное, но программе нужно снова почти столько же времени, пока она не отреагирует.

Цель состоит в том, чтобы сократить время обновления прибл. 50%. Мне нужно отобразить около 200 строк.

Является ли сложенный QTableWidget правильным подходом. Если да, что мне нужно сделать, чтобы оптимизировать время обновления?

Я уже думал об изменении представления с QTableWidget на QGraphicsView и простом рисовании прямоугольников. Или, например, комбинация: использование QTableWidget для заголовка и первых столбцов, а затем объединение всех сложных ячеек и вставка QGraphicsView, но я не уверен, смогу ли я получить правильный размер для нарисованных ячеек, и я делаю не знаю, будет ли время отображения короче.

Ребята, как вы думаете, какой правильный подход к такому столу?

Если вам нужно, я могу добавить функцию, которая обновляет таблицу.

ИЗМЕНИТЬ:

Теперь я использую 2 строки в MainTable для одного блока, что уменьшило количество сложенных виджетов с 2,526 до 7!

Измерение времени для тех же строк теперь выглядит так:

complete update time: ~2s (manually stopped)
time to create the table: 0.572490930557251 (time.time over complete function)
display time: ~1.5s (complete update time - function time)
rows: 160
     20912 function calls in 0.534 seconds

Ordered by: internal time

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
 1417    0.258    0.000    0.258    0.000 {built-in method setCellWidget}
   88    0.209    0.002    0.209    0.002 {built-in method setRowCount}
  163    0.017    0.000    0.017    0.000 {method 'execute' of 'sqlite3.Cursor' objects}
 1410    0.010    0.000    0.010    0.000 {built-in method setStyleSheet}
   80    0.005    0.000    0.005    0.000 {built-in method addWidget}
 1336    0.004    0.000    0.004    0.000 {built-in method setItem}
    7    0.003    0.000    0.004    0.001 DigitalePlanungstafel.py:6037(obenWidgetErstellen)
  501    0.003    0.000    0.003    0.000 {built-in method _pickle.loads}
 1990    0.003    0.000    0.003    0.000 {built-in method cellWidget}
  336    0.002    0.000    0.002    0.000 {method 'strftime' of 'datetime.date' objects}
   83    0.002    0.000    0.004    0.000 _strptime.py:321(_strptime)
 1330    0.002    0.000    0.002    0.000 {method 'format' of 'str' objects}
 1410    0.002    0.000    0.002    0.000 {built-in method setFixedHeight}
  929    0.001    0.000    0.001    0.000 {built-in method setBackground}
 1377    0.001    0.000    0.001    0.000 {built-in method setTextAlignment}
  240    0.001    0.000    0.001    0.000 DigitalePlanungstafel.py:7452(__init__)
  163    0.001    0.000    0.001    0.000 {method 'fetchall' of 'sqlite3.Cursor' objects}
   16    0.001    0.000    0.001    0.000 {built-in method setColumnCount}
  770    0.001    0.000    0.001    0.000 {built-in method setSpan}
 2127    0.001    0.000    0.001    0.000 {built-in method item}
 1570    0.001    0.000    0.001    0.000 {built-in method rowHeight}
   80    0.001    0.000    0.001    0.000 {built-in method setLayout}
   83    0.000    0.000    0.000    0.000 {built-in method _locale.setlocale}
    1    0.000    0.000    0.000    0.000 {built-in method _sqlite3.connect}
  167    0.000    0.000    0.000    0.000 {built-in method setRowHeight}
   89    0.000    0.000    0.000    0.000 {built-in method setForeground}
   83    0.000    0.000    0.000    0.000 {method 'match' of '_sre.SRE_Pattern' objects}
   48    0.000    0.000    0.000    0.000 {built-in method setHorizontalHeaderItem}
   83    0.000    0.000    0.004    0.000 _strptime.py:562(_strptime_datetime)
    7    0.000    0.000    0.000    0.000 {built-in method takeItem}
   80    0.000    0.000    0.000    0.000 {built-in method setContentsMargins}
   83    0.000    0.000    0.004    0.000 {built-in method strptime}
   88    0.000    0.000    0.000    0.000 {built-in method setFont}
  160    0.000    0.000    0.000    0.000 {built-in method setData}
   83    0.000    0.000    0.000    0.000 locale.py:379(normalize)
   80    0.000    0.000    0.000    0.000 {built-in method setAlignment}
   83    0.000    0.000    0.001    0.000 _strptime.py:29(_getlang)
   83    0.000    0.000    0.000    0.000 {method 'groupdict' of '_sre.SRE_Match' objects}
   83    0.000    0.000    0.001    0.000 locale.py:565(getlocale)
    1    0.000    0.000    0.000    0.000 {method 'close' of 'sqlite3.Connection' objects}
    1    0.000    0.000    0.000    0.000 {built-in method io.open}
    7    0.000    0.000    0.000    0.000 {built-in method horizontalHeader}
   80    0.000    0.000    0.000    0.000 {built-in method setUnderline}
  249    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}
   83    0.000    0.000    0.000    0.000 locale.py:462(_parse_localename)
   48    0.000    0.000    0.000    0.000 {built-in method today}
    7    0.000    0.000    0.000    0.000 {built-in method verticalHeader}
  475    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
  167    0.000    0.000    0.000    0.000 {built-in method builtins.len}
  165    0.000    0.000    0.000    0.000 {method 'toordinal' of 'datetime.date' objects}
    1    0.000    0.000    0.000    0.000 {method 'close' of '_io.TextIOWrapper' objects}
  166    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}
    7    0.000    0.000    0.000    0.000 {built-in method setFrameShape}
   27    0.000    0.000    0.000    0.000 {built-in method setColumnWidth}
   84    0.000    0.000    0.000    0.000 {method 'lower' of 'str' objects}
    1    0.000    0.000    0.000    0.000 {method 'sort' of 'list' objects}
   83    0.000    0.000    0.000    0.000 {method 'end' of '_sre.SRE_Match' objects}
   87    0.000    0.000    0.000    0.000 DigitalePlanungstafel.py:6059(<lambda>)
   83    0.000    0.000    0.000    0.000 {method 'keys' of 'dict' objects}
    2    0.000    0.000    0.000    0.000 {built-in method builtins.print}
    7    0.000    0.000    0.000    0.000 {built-in method setFixedSize}
   14    0.000    0.000    0.000    0.000 {built-in method setVisible}
   83    0.000    0.000    0.000    0.000 {method 'weekday' of 'datetime.date' objects}
   96    0.000    0.000    0.000    0.000 {method 'date' of 'datetime.datetime' objects}
    7    0.000    0.000    0.000    0.000 {built-in method setEditTriggers}
   20    0.000    0.000    0.000    0.000 {built-in method columnWidth}
    7    0.000    0.000    0.000    0.000 {built-in method setHorizontalScrollBarPolicy}
    1    0.000    0.000    0.000    0.000 {built-in method _locale._getdefaultlocale}

Время обновления более чем хорошее, но у меня есть 2 проблемы из-за разделения.

  1. Сортировка (по заголовку) больше не работает. Это вызвано слиянием, оно все портит. Есть ли способ заморозить две связанные строки перед сортировкой?

  2. Я хочу, чтобы за раз выбиралась только одна строка. Причина разделения Мне нужно выбрать две связанные строки независимо от того, какая из них выбрана. Ничего особенного, но выглядит не очень хорошо (см. фото).

выбранная строка основной таблицы

выбранная строка основной таблицы


  • Чтобы иметь быстрый графический интерфейс, вам определенно нужно использовать QTableView (с моделью). 17.12.2018
  • Вам нужно более четко объяснить, почему вы используете таблицы внутри таких таблиц. Вы просто используете их как быстрый и грязный способ сложного форматирования в ячейках? Если это так, гораздо лучшим подходом будет использование элемента -delegates, которые затем могут рисовать ячейки напрямую. Это также позволит вам использовать настраиваемые виджеты редактирования, если ячейки не доступны только для чтения. 17.12.2018
  • Я использую таблицы внутри таблиц, потому что это единственный подход, которым я смог управлять для сложного форматирования. Ячейки доступны только для чтения (NoEditTriggers). Я новичок в Python и QT, поэтому я не хочу делать это слишком сложным. На данный момент моя идея состоит в том, чтобы использовать 2 строки вместо одной и объединить первые 6 строк, что должно значительно уменьшить сложенные таблицы - я дам вам знать, насколько это будет быстрее, как только я закончу. 18.12.2018

Ответы:


1

Вы не хотите делать ничего из этого - вместо этого:

  1. Используйте модель для ваших данных.

  2. Используйте модель представления, которая адаптирует модель к представлению, которое вы хотите иметь.

  3. Используйте QTableView для отображения модели представления.

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

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..