LINUX.ORG.RU

Полосы прокрутки для большого объема данных

 ,


0

1

Я делаю widget для отображения большого набора данных (миллионы строк). Обычные полосы прокрутки тут бесполезны, так как движение на 1 пиксель приводит с скачку на десятки тысяч строк.

Особенностью данных является локальность, так что чаще всего работа будет происходить в ограниченном окне (~1000 строк). И начальная абсолютная позиция устанавливается извне. Но прокрутка должна быть непрерывной.

Моя идея - при достижении крайних положений, сдвигать диапазон значений полосы прокрутки вниз или вверх.

Но не покидает общее ощущение велосипедности этого решения. Как вообще такое обычно делают? Есть примеры ПО, где подобное реализовано?

★★★★

У QAbstractItemModel есть методы canFetchMore и fetchMore. При достижении низа при прокрутке можно подгружать новые данные, например.

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

grondek
()
Последнее исправление: grondek (всего исправлений: 1)

Голосую за разбитие на страницы (табы). Самое разумное решение.

Deleted
()
Ответ на: комментарий от grondek

Не подходит. Это может только растить данные вниз. Нужно, чтобы полоса прокрутки всегда прокручивала только фиксированный набор строк.

Ну и еще это не QAbstractItemModel, а наследник от QAbstractScrollArea, но это не так важно.

alexru ★★★★
() автор топика
Ответ на: комментарий от grondek

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

Данные динамически вычитаются из внешнего устройства, так что только небольшой объем кешируется локально, с этим проблем нет.

Разбить не получается, у данных нет логических границ.

alexru ★★★★
() автор топика
Ответ на: комментарий от alexru

Ну сделай два скроллбара. Один будет перемещать твоё «окно» длиной 10к строк по всему файлу, а второй будет осуществлять прокрутку в этом «окне». Хотя получится фигня какая-то.

WRG ★★★★
()
Ответ на: комментарий от alexru

Разбить не получается, у данных нет логических границ.

Страница будет просто вмещать N очередных строк. Тут не надо никакой логической разбивки.

grondek
()

Вообще тупо скролл по миллиону строк нафиг никому не нужен, потому как заколебешься позиционировать на нужные данные. Часто такие объемы данных скроллят уже после какой-либо фильтрации.

grondek
()

Посмотри на реализацию прокрутки и навигации в плеерах (vlc, smplayer).

Deleted
()
Ответ на: комментарий от grondek

Страница будет просто вмещать N очередных строк. Тут не надо никакой логической разбивки.

Не пойдет. Данные выводятся для анализа людьми, люди хотят видеть слитные данные.

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

Задача абсолютного положения внутри миллионов строк от полос прокрутки не требуется.

alexru ★★★★
() автор топика
Ответ на: комментарий от alexru

Тогда давай подробнее, что за данные, которые должны быть слитные и которых миллион строк и которые должен видеть человек (как он в этих миллионах строк разбираться будет - это уже другой вопрос).

Как вариант: сделай скролл скроллером мыши.

grondek
()

как вариант:
1. запретить скроллбар справа
2. нарисовать его снизу (как в плеерах)
3. тамже поле ввода вручную строки
4. кнопка на 1 строку вниз (хоткей стрелка вниз)
5. кнопка на 1 строку вверх (хоткей стрелка вверх)
6. кнопка на 1 страницу вверх (хоткей pgup)
7. кнопка на 1 страницу вниз (хоткей pgdn)
8. кнопка на 1% строк вниз (хоткей стрелка вправо)
9. кнопка на 1% строк вверх (хоткей стрелка влево)

x905 ★★★★★
()
Ответ на: комментарий от grondek

Тогда давай подробнее, что за данные, которые должны быть слитные и которых миллион строк и которые должен видеть человек

Самая простая аналогия - бинарный редактор на /dev/mem. Полный объем документа может измеряться гигабайтами. Переход в нужный адрес - по команде извне. Но как только оказались в нужном месте - необходима возможность непрерывной прокрутки. Ну и если хочется, то крути хоть все гигабайты.

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

alexru ★★★★
() автор топика
Ответ на: комментарий от alexru

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

arturpub ★★
()
Ответ на: комментарий от alexru

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

Закладочки можно сделать по ctrl-123.

arturpub ★★
()
Ответ на: комментарий от arturpub

Фильтр (окно) само должно двигаться при подходе к границам.

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

alexru ★★★★
() автор топика
Ответ на: комментарий от alexru

И не только ощущаются, но и реализовываются с костылями, что намекает на то, что я делаю что-то не так.

У QScrollBar сигнал valueChanged() вызывается даже при ручной установке нового положения. Но новое положение нужно устанавливать в valueChanged() при достижении пределов. Полной рекурсии не получается из-за того как организованы сигналы, но выглядит криво все-равно.

alexru ★★★★
() автор топика
Последнее исправление: alexru (всего исправлений: 1)

А вообще по твоему описанию пойдет такое:

1. скроллбар не трогай 2. скролл мышой (ее скроллером) на поле виджета (возможно, с нажатым ctrl) и клавишами вверх-вниз 3. переход на нужную строку по введенному значению (типа поиск) или номеру строки 4. Как уже писали выше - обязательны закладки и переход к предыдущим положениям в списке

grondek
()

Можно сделать свой компонент, который будет сам грузить и подтирать ненужные строки. У QTableWidget есть свойства которые говорят об области видимости - вот на базе него. Но чтобы добиться плавности прокрутки наверное придется как-то потрудиться дополнительно...

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от grondek

есть такой костыль:

Замечательно. Костыль помог. Сделал для теста следующее:

1. Диапазон ScrollBar-а 0-10000 (окно). Смещение окна = 0.

2. При достижении 10000 положение устанавливается в 9000 и к смещению прибавляется 1000.

3. При достижении 0, положение устанавливается в 1000 и от смещения отнимается 1000.

4. При отрисовке запрашиваются данные по смещение + положение ScrollBar-а.

Таким образом ScrollBar всегда имеет диапазон 0-10000 и не нужно бороться с ограничениями на максимальное положение (signed int).

С реальными данными не проверял, но на тестовых пустышках все выглядит хорошо и ощущается естественно и приятно.

В добавок ко всему, быстрая прокрутка осуществляется захватом ползунка, удавливанием его вниз и возней мышкой вправо и влево.

alexru ★★★★
() автор топика
Последнее исправление: alexru (всего исправлений: 2)

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

zezic ★★★★
()
Последнее исправление: zezic (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.