Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Павел_F. от Ноябрь 12, 2009, 15:49



Название: Чем большой текст показать?
Отправлено: Павел_F. от Ноябрь 12, 2009, 15:49
По условиям задачи есть большой текст. Очень большой. Хранится он в QStringList. Причем в одном QString может быть несколько строк ( символов /n). Нужно весь этот текст показать. Если в лоб пихать все в что-то типа QTextEdit то работает очень медленно. Как организовать просмотр этого?


Название: Re: Чем большой текст показать?
Отправлено: lit-uriy от Ноябрь 12, 2009, 15:58
А в QLabel?


Название: Re: Чем большой текст показать?
Отправлено: Павел_F. от Ноябрь 12, 2009, 16:22
Эм... Да он, вроде, не совсем приспособлен для этого... Там и поиск надо будет и печать оттуда.... все кроме редактирования. А если лайбел и покажет "без тормозов" то прикручивать к нему новые бусы и ворочать здоровый QString ( чтоб была функциональность) для него думаю выйдет накладно.


Название: Re: Чем большой текст показать?
Отправлено: crossly от Ноябрь 12, 2009, 16:30
По условиям задачи есть большой текст. Очень большой. Хранится он в QStringList. Причем в одном QString может быть несколько строк ( символов /n). Нужно весь этот текст показать. Если в лоб пихать все в что-то типа QTextEdit то работает очень медленно. Как организовать просмотр этого?
каким образом текст в textedit вписывается..... код показать можешь??


Название: Re: Чем большой текст показать?
Отправлено: sLiva от Ноябрь 12, 2009, 18:12
По условиям задачи есть большой текст. Очень большой. Хранится он в QStringList. Причем в одном QString может быть несколько строк ( символов /n). Нужно весь этот текст показать. Если в лоб пихать все в что-то типа QTextEdit то работает очень медленно. Как организовать просмотр этого?

Начиная с версии 4.4 появился такой QPlainTextEdit:
http://qt.nokia.com/doc/4.5/qplaintextedit.html

Сам не тестил но написано что очень быстрый


Название: Re: Чем большой текст показать?
Отправлено: Павел_F. от Ноябрь 13, 2009, 13:11
Попробовал и QTextEdit и QPlainTexEdit. Одинаковая картина везде. Очень много времени надо на добавление текста ( добавлять пробовал по разному, на результат не влияет) и тормозит скроллинг. Может где есть что-то готовое типа постраничного просмотра? Типа смотрелка логов на Qt...


Название: Re: Чем большой текст показать?
Отправлено: BaltikS от Ноябрь 13, 2009, 18:37
Павел_F., попробуй скомпилить в release. Часто бывает, что release версия работает гораздо быстрее...


Название: Re: Чем большой текст показать?
Отправлено: lit-uriy от Ноябрь 13, 2009, 19:36
>>По условиям задачи есть большой текст. Очень большой.
Сколько метров файл?


Название: Re: Чем большой текст показать?
Отправлено: sLiva от Ноябрь 13, 2009, 19:53
Попробовал и QTextEdit и QPlainTexEdit. Одинаковая картина везде. Очень много времени надо на добавление текста ( добавлять пробовал по разному, на результат не влияет) и тормозит скроллинг. Может где есть что-то готовое типа постраничного просмотра? Типа смотрелка логов на Qt...

Попробуй поиграться со свойством maximumBlockCount у QPlainTexEdit (http://qt.nokia.com/doc/4.5/qplaintextedit.html#maximumBlockCount-prop)

Из документации:

Цитировать
If you want to limit the total number of paragraphs in a QPlainTextEdit, as it is for example useful in a log viewer, then you can use the maximumBlockCount property.

Возможно решит проблему с скороллингом ну и загрузкой.
А так и вправду покажи код заполнения QPlainTexEdit, и каков размер файла?


Название: Re: Чем большой текст показать?
Отправлено: Павел_F. от Ноябрь 16, 2009, 11:29
Обсуждали задачу еще раз, она просто на этапе формирования... Концепция поменялась. Нужно писать смотрелку для лога. Текстовый файл, может быть гигов до пяти. Нужно организовать его просмотр, точнее виджет с его просмотром. Может кто посоветует где что-нибудь подглядеть на данную тему?


Название: Re: Чем большой текст показать?
Отправлено: Пантер от Ноябрь 16, 2009, 12:23
Я пытался такую вещь сделать для своего проекта, но пока отложил. Лучший пример - вьювер в TotalCommander. Смысл такой:
1. Открываем файл на чтение.
2. Расчитываем кол-во строк в файле (это пока самое проблемное место).
3. У скролбара устанавливаем максимальную границу.
4. Считываем видимые строки из файла и отображаем их на каком-либо виджете (я использовал QWidget).
5. При скролинге считываем новые видимые строки (предыдущие удаляем) и повторяем отображение.
У меня сейчас нет возможности заниматься сей задачей. Если сделает кто-нибудь и угостит кодом, буду очень благодарен. Если что-то по алгоритму не ясно, спрашивай.


Название: Re: Чем большой текст показать?
Отправлено: Павел_F. от Ноябрь 16, 2009, 13:03
Кол-во строк не проблема... Как вычислить сколько строк в какой-нибудь QTextEdit влезет?


Название: Re: Чем большой текст показать?
Отправлено: Igors от Ноябрь 16, 2009, 13:05
Я пытался такую вещь сделать для своего проекта, но пока отложил. Лучший пример - вьювер в TotalCommander. Смысл такой:
1. Открываем файл на чтение.
2. Расчитываем кол-во строк в файле (это пока самое проблемное место).
Можно не спешить с этим, а строить индекс (строка - ее позиция в файле) по частям/запросу. Скроллбар привязать к размеру файла. Если найду время (на этой неделе много тупой работы) - попробую, хорошая возможность поизучать на деле.    


Название: Re: Чем большой текст показать?
Отправлено: Пантер от Ноябрь 16, 2009, 17:32
Igors: буду очень благодарен, если сделаешь.
Кстати, можно немного облегчить дело если переносить строки после ХХ(допустим 80) символов, тогда легче посчитать будет. В идеале нужна поддержка обоих режимов. Если знаешь паскаль, можно код посмотреть в http://atorg.net.ru/delphi/atviewer.htm


Название: Re: Чем большой текст показать?
Отправлено: Igors от Ноябрь 26, 2009, 07:55
Ну вот что у меня получилось (attachment). В 2 словах это  viewer который не загружает весь файл в память, а работает "окном" (т.е. держит в памяти всего несколько страниц текста). В архиве также утилитка чтобы создавать текстовые файлы приличного размера (1 Gb и более). Проблемы:

- разумеется никаких шрифтов, html и.т.п - только plain text
- русского языка нет (может и можно сделать но я не знаю как)
- режим "wrap" (с переносом текста) вылетает. И многое для этого режима не сделано

Впечатления: "мало не показалось" :)  Как оно часто бывает, на деле все сложнее чем сначала думалось


Название: Re: Чем большой текст показать?
Отправлено: spectre71 от Ноябрь 26, 2009, 12:19
Ну вот что у меня получилось (attachment). В 2 словах это  viewer который не загружает весь файл в память, а работает "окном" (т.е. держит в памяти всего несколько страниц текста). В архиве также утилитка чтобы создавать текстовые файлы приличного размера (1 Gb и более). Проблемы:

- разумеется никаких шрифтов, html и.т.п - только plain text
- русского языка нет (может и можно сделать но я не знаю как)
- режим "wrap" (с переносом текста) вылетает. И многое для этого режима не сделано

Впечатления: "мало не показалось" :)  Как оно часто бывает, на деле все сложнее чем сначала думалось

Не заработало. Показывает только первую строчку в файле.


Название: Re: Чем большой текст показать?
Отправлено: BigZ от Ноябрь 26, 2009, 12:44
Ну вот что у меня получилось (attachment). В 2 словах это  viewer который не загружает весь файл в память, а работает "окном" (т.е. держит в памяти всего несколько страниц текста). В архиве также утилитка чтобы создавать текстовые файлы приличного размера (1 Gb и более). Проблемы:

- разумеется никаких шрифтов, html и.т.п - только plain text
- русского языка нет (может и можно сделать но я не знаю как)
- режим "wrap" (с переносом текста) вылетает. И многое для этого режима не сделано

Впечатления: "мало не показалось" :)  Как оно часто бывает, на деле все сложнее чем сначала думалось
Другой вариант воспользоваться QStringListModel (если строки в QStringList как в начальном условии), которую подключить к QTableView. Если лог ОЧЕНЬ! большой и в файле, то нужна своя модель в которой кол. строк равно кол. строк в файле.
P.S. Но я не знаю QTableView кеширует данные модели или нет, может память кушать.



Название: Re: Чем большой текст показать?
Отправлено: spectre71 от Ноябрь 26, 2009, 13:07
Другой вариант воспользоваться QStringListModel (если строки в QStringList как в начальном условии), которую подключить к QTableView. Если лог ОЧЕНЬ! большой и в файле, то нужна своя модель в которой кол. строк равно кол. строк в файле.
P.S. Но я не знаю QTableView кеширует данные модели или нет, может память кушать.

Этот вариант в данном случае абсолютно не подходит.
Речь не о визуализации лога, а просмотрщике файлов. С Врапингом, селекцией участков текста итд.


Название: Re: Чем большой текст показать?
Отправлено: Igors от Ноябрь 26, 2009, 17:57
Не заработало. Показывает только первую строчку в файле.
Не знаю как решить - у меня показывает все ???
Какой файл смотрите? Попробуйте с файлом созданным утилитой - я гонял на них


Название: Re: Чем большой текст показать?
Отправлено: Павел_F. от Ноябрь 27, 2009, 15:23
Добрался, наконец, до него еще раз. Что-то слепил.
Вариант предложенный Igors у меня компилится что-то не хочет...
Цитировать
MainWindow.o: In function `(anonymous namespace)::LoadDialog(QWidget*, char const*)':
MainWindow.cpp:(.text+0x1678): undefined reference to `QFormBuilder::QFormBuilder()'
MainWindow.cpp:(.text+0x172f): undefined reference to `QAbstractFormBuilder::load(QIODevice*, QWidget*)'
MainWindow.cpp:(.text+0x1754): undefined reference to `QFormBuilder::~QFormBuilder()'
MainWindow.cpp:(.text+0x1b59): undefined reference to `QFormBuilder::~QFormBuilder()'

Хотя особо не разбарался, не захотело и ладно.


Название: Re: Чем большой текст показать?
Отправлено: Igors от Ноябрь 27, 2009, 18:04
Добрался, наконец, до него еще раз. Что-то слепил.
Вариант предложенный Igors у меня компилится что-то не хочет...
Цитировать
MainWindow.o: In function `(anonymous namespace)::LoadDialog(QWidget*, char const*)':
MainWindow.cpp:(.text+0x1678): undefined reference to `QFormBuilder::QFormBuilder()'
MainWindow.cpp:(.text+0x172f): undefined reference to `QAbstractFormBuilder::load(QIODevice*, QWidget*)'
MainWindow.cpp:(.text+0x1754): undefined reference to `QFormBuilder::~QFormBuilder()'
MainWindow.cpp:(.text+0x1b59): undefined reference to `QFormBuilder::~QFormBuilder()'

Хотя особо не разбарался, не захотело и ладно.
Не хочет линковаться потому что нет либы QDesigner. Ну да ладно, "не разбарался" - так не разбарался :)

В Вашем варианте не работает тетя Клава (нельзя выйти за пределы загруженной порции нажимая PgUp, PgDown или стрелки). Дело вкуса но мигание + индикация при таскании скроллбара по-моему не смотрятся. Навигацию и поиск видимо добавить придется. И еще позвольте заметить:

Цитировать
Что-то слепил.
Зачем так пренебрежительно говорить о своей работе над которой Вы сидели не один день? То что Вы сделали - совсем НЕ просто (сам проверял  :))


Название: Re: Чем большой текст показать?
Отправлено: Павел_F. от Ноябрь 27, 2009, 18:19
Не хочет линковаться потому что нет либы QDesigner.
Надо поставить, хотя пока не до этого.
В Вашем варианте не работает тетя Клава (нельзя выйти за пределы загруженной порции нажимая PgUp, PgDown или стрелки). Дело вкуса но мигание + индикация при таскании скроллбара по-моему не смотрятся. Навигацию и поиск видимо добавить придется.
Это понятно, я в описании и написал что только скролбар и колесо мыши. Тут от задачи все зависит. Если шаг большой поставить то индексироваться будет быстрее и памяти надо меньше а вот поиск строки будет долгим и без индикации прога выглядит "повисшей". Добавить нужно еще много чего и много чего переделать/пересмотреть... это "первый шаг".
Зачем так пренебрежительно говорить о своей работе над которой Вы сидели не один день? То что Вы сделали - совсем НЕ просто (сам проверял  :))
Потому что до приличного вида этому еще далеко. Да и сидел один день, точнее одни сутки :) . Но согласен, не так просто как казалось...


Название: Re: Чем большой текст показать?
Отправлено: Igors от Ноябрь 27, 2009, 19:00
Тут от задачи все зависит. Если шаг большой поставить то индексироваться будет быстрее и памяти надо меньше а вот поиск строки будет долгим и без индикации прога выглядит "повисшей".
Я пробовал QTextStream но на гигабайтах он работает гнусно медленно. Прямое чтение в несколько раз быстрее. И, к сожалению, QTextStream не все концы строк понимает. С размером "шага" по-моему все ясно: число строк в экране умноженное на 3. То есть имеем запас - экран текста вверх, экран текста вниз.


Название: Re: Чем большой текст показать?
Отправлено: Павел_F. от Ноябрь 27, 2009, 20:10
У меня сначала читаются, но не хранятся, все строки по очереди ( для подсчета их кол-ва и заполнения массива индексов). Массив индексов это тупо массив целых чисел ( число это позиция строки в файле). В массиве я храню только строки с номерами кратными шагу ( например если шаг зададим 1000 то там будут 0-я, 1000-я, 2000-я и т.д.). Поэтому массив сравнительно не большой и его размер обратно пропорционален размеру шага. Далее, когда мне нужна строка с номером n, я n представляю для себя в виде step*k + m, ищу в массиве позицию строки с номером k, смещаюсь в файле на позицию строки k. И начиная с этой позиции ищу строку с номером m ( это и будет моя строка n). Время этого поиска мноооого меньше поиска по всему файлу( в худшем случае я переберу количество строк равное размеру шага) и прямо пропорционально размеру шага. Вот выбор размера шага... это только из опытов :)

При таком подходе переход k строк вперед и на x*n + k занимает одинаковое время( k - количество строк, n - размер шага индексирования, х - любое целое). Т.е. я могу шагнуть на 1 строку и на 1001 за одинаковое время ( ну не совсем, но почти. разница во времени поиска в QList от использования которого думаю отказаться и времени смещения по файлу но это отдельная тема). при этом можно обойтись малым кол-вом памяти( порядка мегабайта при работе с трех гигабайтным файлом). И я не храню содержимое файла в памяти( только то что видно на экране и то уже в визуальном компоненте) и не реализовываю никакого упреждающего чтения. При моей задаче это важно и всякие QTextStream'ы тут совершенно не подходят.
При упреждающем чтении сложно смещаться сразу на много "страниц" я же без проблем получу "страницу" хоть из середины хоть сначала, хоть с конца ( и в получении этих "страниц" практически на будет разницы).
Понятие "шаг" у вас и у меня несут несколько разный смысл.

Хотя, как я говорил, это лишь "первое приближение" нужной вещи.
Далеко не всегда стоит так "мудрить". Если дело касается, например, просто листания и разглядывания файла то это совершенно не нужно.
PS: а вот с тем как QFile::readLine() определяет конец строки меня, видимо, еще ждет нехороший сюрприз...


Название: Re: Чем большой текст показать?
Отправлено: Igors от Ноябрь 27, 2009, 20:34
Мне кажется Вы перемудрили с оптимизацией пл памяти. Я храню тупо: строка - ее позиция в файле (qint64, 8 байт). Давайте прикинем: миллион строк (приличный текстовик) - съедается 8Mb. Это разумный расход памяти. Сократить в 2 раза - не вопрос, например

Код:
struct CIndex : public QVector <int> {
... 
qint64 LinePosition( int index ) { return mBasePosition[i / mBlockSize] + at(i); }
...
  QVector <qint64> mBasePosition;
};


Название: Re: Чем большой текст показать?
Отправлено: Павел_F. от Ноябрь 27, 2009, 20:40
"Бытие определяет сознание." (c)
Если памяти нет, то взять ее уже негде.


Название: Re: Чем большой текст показать?
Отправлено: Igors от Ноябрь 27, 2009, 20:54
"Бытие определяет сознание." (c)
Если памяти нет, то взять ее уже негде.
Да помилуйте, вот сегодня, здесь, обсуждал с человеком масштабирование картинки до размера типа 2000x2000 (это всего лишь 16 Mb). И это очень скромно по сегодняшним понятиям.


Название: Re: Чем большой текст показать?
Отправлено: Павел_F. от Ноябрь 27, 2009, 20:58
Ну это уже личное дело каждого.
Хотя, возможно, требования по расходу памяти не столь жестки как я их воспринял. И если это окажется так то я с радостью переделаю и не буду так "мудрить".


Название: Re: Чем большой текст показать?
Отправлено: lit-uriy от Декабрь 14, 2009, 08:17
Igors, коррективы твоей программы:
во все pro-файлы добавить:
Код
C++ (Qt)
CONFIG += designer

в генератор файлов, в функции Generate заменить строку:
Код
C++ (Qt)
s += lst[RandInt(0, lst.size())];
на
Код
C++ (Qt)
s += lst[RandInt(0, lst.size()-1)];
иначе во время генерации крашится по ASSERT'у в QList


Название: Re: Чем большой текст показать?
Отправлено: daimon от Декабрь 14, 2009, 10:58
Просматиривая большой файл (300 метров), возникла ошибка при перемещении ползунка скрола мышой (debug показал ошибку в qvector.h -> inline bool isEmpty() const { return d->size == 0;} )


Название: Re: Чем большой текст показать?
Отправлено: Павел_F. от Декабрь 14, 2009, 11:04
300 метров это не большой файл, тут рассуждения о файлах от 2Гб. И кому адресован вопрос уточните, а то непонятно что вы пробовали и как.


Название: Re: Чем большой текст показать?
Отправлено: Igors от Декабрь 14, 2009, 14:10
Igors, коррективы твоей программы:
во все pro-файлы добавить:
Код
C++ (Qt)
CONFIG += designer

в генератор файлов, в функции Generate заменить строку:
Код
C++ (Qt)
s += lst[RandInt(0, lst.size())];
на
Код
C++ (Qt)
s += lst[RandInt(0, lst.size()-1)];
иначе во время генерации крашится по ASSERT'у в QList
Спасибо, Юра, про CONFIG просто не знал :)


Название: Re: Чем большой текст показать?
Отправлено: Igors от Декабрь 14, 2009, 14:12
Просматиривая большой файл (300 метров), возникла ошибка при перемещении ползунка скрола мышой (debug показал ошибку в qvector.h -> inline bool isEmpty() const { return d->size == 0;} )
Вот и исправьте и выложите обновленный вариант, больше толку будет чем месить QHash для spreadsheet :)


Название: Re: Чем большой текст показать?
Отправлено: lit-uriy от Декабрь 14, 2009, 14:49
Цитировать
про CONFIG просто не знал
я как на ошибку компиляции наткнулся, полез смотреть в Асистент о классе QFormBuilder. Увидел, что он в модуле QtDesigner, а там в подробном описании (http://www.doc.crossplatform.ru/qt/4.5.0/qtdesigner.html#details) написано как подключить

Правда для меня логичнее было бы так:
Код
Bash
QT += designer
т.е. по аналогии с:
Код
Bash
QT -= gui





Название: Re: Чем большой текст показать?
Отправлено: lit-uriy от Декабрь 14, 2009, 14:51
П.С. к слову сказать просмотрщик у меня не работает, так как ожидалось. Имеется файл, неслишком большой, много строчек, строчки нумерованы (создан твоей утилитой). В Тоталкомандере по F3 вижу строчки нумерованные. А В LargeTextView только первую строку и море пустых


Название: Re: Чем большой текст показать?
Отправлено: Igors от Декабрь 14, 2009, 15:57
П.С. к слову сказать просмотрщик у меня не работает, так как ожидалось. Имеется файл, неслишком большой, много строчек, строчки нумерованы (создан твоей утилитой). В Тоталкомандере по F3 вижу строчки нумерованные. А В LargeTextView только первую строку и море пустых
Наконец воспроизвелось и я увидел где это (ошибка при отлове конца строки для Вындоуз). Подправил (attachment).

Насчет CONFIG += designer теряюсь в догадках. На одном проекте (из архива) все нормально, добавляет либу в созданный проект. На другом нет. Почему - хз  :)  Я на XCode просто беру QtDesigner framework и дроплю в проект - секундное дело.


Название: Re: Чем большой текст показать?
Отправлено: daimon от Декабрь 14, 2009, 17:59
300 метров это не большой файл, тут рассуждения о файлах от 2Гб. И кому адресован вопрос уточните, а то непонятно что вы пробовали и как.
Программа LargeTextView, загрузил файл повозился с прокруткой - ошибка в классе вектора


Название: Re: Чем большой текст показать?
Отправлено: lit-uriy от Декабрь 14, 2009, 20:11
>>ошибка в классе вектора
daimon, ты случаем на партизана нигде не учился?


Название: Re: Чем большой текст показать?
Отправлено: daimon от Декабрь 14, 2009, 20:43
>>ошибка в классе вектора
daimon, ты случаем на партизана нигде не учился?
qvector - ошибка в возврате размера


Название: Re: Чем большой текст показать?
Отправлено: spectre71 от Декабрь 15, 2009, 01:05
Наконец воспроизвелось и я увидел где это (ошибка при отлове конца строки для Вындоуз). Подправил (attachment).

Попробовал запустить на большом файле 357 MB
1) После загрузки файла - показывает только первые несколько строчек на видимую страницу. После нескольких скролирований начинает показывать всю видимую страницу
2) При скролировании с включенным Wrap - падает
3) Не смог обработать ошибочные комбинации переносов строк возникающие при переносе и редактировании файла под разными системами (win->mac->lin>win->..). Пример такого файла ("lines-bad.txt") описание("info.txt"), конечный автомат("fsm.txt") для правильного разбора и его код("fsm.cpp.txt") в архиве "lines.zip"
 


Название: Re: Чем большой текст показать?
Отправлено: Igors от Декабрь 15, 2009, 15:53
Попробовал запустить на большом файле 357 MB
1) После загрузки файла - показывает только первые несколько строчек на видимую страницу. После нескольких скролирований начинает показывать всю видимую страницу
2) При скролировании с включенным Wrap - падает
3) Не смог обработать ошибочные комбинации переносов строк возникающие при переносе и редактировании файла под разными системами (win->mac->lin>win->..). Пример такого файла ("lines-bad.txt") описание("info.txt"), конечный автомат("fsm.txt") для правильного разбора и его код("fsm.cpp.txt") в архиве "lines.zip"
 
- С критикой концов строк вынужден согласиться, но в автоматах/пулеметах я не силен  :) поэтому решил по-своему (attachment). Заодно поправил еще ошибку (lines-bad.txt не реагировал на сколлер)

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

- с wrap хуже всего, у меня нет даже идей и неясно почему он падает   :-\

И вообще: исходники есть, так что исправляем, дополняем, пишем свои реализации и.т.п. :)