Название: html-форматирование в QTableView Отправлено: tamplier от Май 09, 2020, 18:19 Уважаемые форумчане!
Скажите, пожалуйста, каким образом можно "прикрутить" отображение строк с html-форматированием в QTableView? Если упростить, то ситуация следующая (просто не знаю даже куда копать): есть список строк QStringList. Есть модель QStringListModel, которая является моделью данного списка и есть представление QTableView, которое отображает список строк (модели) с одним столбцом. Необходимо чтобы определенные буквы в представлении (в строках) отображались жирным шрифтом (либо, как-то выделялись)... Понятно, что в контексте QStringList и QStringListModel данную задачу решить не получится. Были мысли использовать QList<QLabel *> с QAbstractListModel. Но не могу понять как это всё реализовать... Еще как вариант использовать делегат, но с темой делегатов я на Вы, почитав книги М.Шлее и Ж.Бланшет и М.Саммерфилд, так и не разобрался с данной темой, да и как оказалось, то, что легко понимается в теории, зачастую на практике применить не получается... Итог: реализовав бОльшую часть приложения запнулся на казалось бы пустяковой задаче. Буду признателен любым советам по теме. Подскажите хотя бы куда копать. Использовать делегаты? Как-то прикрутить список указателей на QLabel-ы? Может QSyntaxHighlighter поможет? Или есть другой вариант, как выделить определенные буквы в списке строк в QTableView... Направьте на путь истинный... :) P.S.: Может посоветуете что почитать на тему делегатов, буду очень признателен. Название: Re: html-форматирование в QTableView Отправлено: Igors от Май 10, 2020, 12:53 Использовать делегаты? Как-то прикрутить список указателей на QLabel-ы? А если просто в методе модели data (DisplayRole) формировать нужную html строку из исходной?Название: Re: html-форматирование в QTableView Отправлено: Пантер от Май 15, 2020, 20:03 Используй делегаты, это именно то, что тебе нужно.
Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 20, 2020, 20:35 Использовать делегаты? Как-то прикрутить список указателей на QLabel-ы? А если просто в методе модели data (DisplayRole) формировать нужную html строку из исходной?Было бы замечательно, но метод возвращает тип QVariant и к типу QLabel его не приведешь (чтобы отображать в представлении текст отформатированный в стиле html). Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 20, 2020, 20:56 Спасибо большое за подсказки!
Решил проблему следующим способом (может кому пригодится): delegate.h: Код
delegate.cpp: Код
main.cpp: Код
Честно признаюсь решением не доволен... Хоть и списки для форматированного вывода в итоге должны быть небольшими, всё-равно не хочется элементами представления делать такие "тяжелые" виджеты, как QTextDocument... Но так и не придумал, как "прикрутить" к модели QTableView виджет QLabel. В сети и в справке ничего вразумительного так и не нашел, может плохо искал... Название: Re: html-форматирование в QTableView Отправлено: Пантер от Май 20, 2020, 21:26 Я помню, когда-то свой делегат чекбокса писал. Поищи, должна быть возможность QLabel заюзать.
https://www.qtcentre.org/threads/30594-QItemDelegate-with-QLabel-for-QTableView Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 06:23 Да, пробовал подобный вариант. Но переопределение методов createEditor и setEditorData предполагает, что будет редактирование модели через представление. В моем случае этого не надо. И если реализовать свой делегат подобным образом, то текст в представлении отображается некорректно, виджет QLabel как-бы накладывается на текст (происходит дублирование).
В моем случае это выглядит так: (https://a.radikal.ru/a14/2005/4e/4498266ba93b.png) (https://radikal.ru) Код следующий: delegate.h: Код
delegate.cpp: Код
main.cpp: Код
Название: Re: html-форматирование в QTableView Отправлено: Пантер от Май 21, 2020, 07:31 А куда ты дел все, что связано с QStyleOptionViewItem? Ты же должен не только создать виджет, но и корректно его разместить.
Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 09:20 А куда ты дел все, что связано с QStyleOptionViewItem? Ты же должен не только создать виджет, но и корректно его разместить. Уважаемый Пантер, не очень понимаю, что ты имеешь ввиду... Хотя бы пару строчек кода, или ссылку на пример... Куда и как именно я должен разместить "все, что связано с QStyleOptionViewItem"? Название: Re: html-форматирование в QTableView Отправлено: Пантер от Май 21, 2020, 09:28 tamplier, у тебя же выше был код HtmlDelegate::paint. Для QLabel тоже нужно реализовать этот метод и правильно разместить виджет.
Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 09:37 tamplier, у тебя же выше был код HtmlDelegate::paint. Для QLabel тоже нужно реализовать этот метод и правильно разместить виджет. Да. Я понимаю, что это логично, именно метод paint использовать для отображения QLabel в представлении... Но у меня затык в том, что QLabel не содержит метод drawContents, и аналогичного я не нашел. Не могу понять как отрисовать виджет QLabel в итеме... :-[ Название: Re: html-форматирование в QTableView Отправлено: Пантер от Май 21, 2020, 10:17 https://doc.qt.io/qt-5/qwidget.html#grab
https://doc.qt.io/qt-5/qwidget.html#render Может, куда-то сюда покопать... Название: Re: html-форматирование в QTableView Отправлено: Igors от Май 21, 2020, 11:14 Было бы замечательно, но метод возвращает тип QVariant и к типу QLabel его не приведешь (чтобы отображать в представлении текст отформатированный в стиле html). А просто QString в html?Название: Re: html-форматирование в QTableView Отправлено: Пантер от Май 21, 2020, 11:20 Было бы замечательно, но метод возвращает тип QVariant и к типу QLabel его не приведешь (чтобы отображать в представлении текст отформатированный в стиле html). А просто QString в html?Название: Re: html-форматирование в QTableView Отправлено: ViTech от Май 21, 2020, 11:27 Не могу понять как отрисовать виджет QLabel в итеме... :-[ QAbstractItemView::setIndexWidget (https://doc.qt.io/qt-5/qabstractitemview.html#setIndexWidget) пробовали? Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 11:33 https://doc.qt.io/qt-5/qwidget.html#grab https://doc.qt.io/qt-5/qwidget.html#render Может, куда-то сюда покопать... Спасибо ОГРОМНОЕ! Очень помог! Название: Re: html-форматирование в QTableView Отправлено: Пантер от Май 21, 2020, 11:42 https://doc.qt.io/qt-5/qwidget.html#grab https://doc.qt.io/qt-5/qwidget.html#render Может, куда-то сюда покопать... Спасибо ОГРОМНОЕ! Очень помог! Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 11:46 Благодаря тому, что Пантер дал мне правильную подсказку (указал на нужный метод), получилось следующее:
htmldelegat.h Код
htmldelegat.cpp Код
main.cpp Код
Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 11:48 Наверное это единственный форум, где решена проблема отображения QLabel в QTableView :). Тему можно закрывать.
Название: Re: html-форматирование в QTableView Отправлено: Пантер от Май 21, 2020, 11:54 Отлично! Пусть теперь кешируется в поисковиках. :)
Название: Re: html-форматирование в QTableView Отправлено: Igors от Май 21, 2020, 12:12 QLabel нужен для рендеринга. А нужен ли? Если просто так дать таблице/ячейке html строку, она что, эту строку не отрендерит ? Стоит проверитьНазвание: Re: html-форматирование в QTableView Отправлено: Пантер от Май 21, 2020, 12:43 QLabel нужен для рендеринга. А нужен ли? Если просто так дать таблице/ячейке html строку, она что, эту строку не отрендерит ? Стоит проверитьНазвание: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 12:44 QLabel нужен для рендеринга. А нужен ли? Если просто так дать таблице/ячейке html строку, она что, эту строку не отрендерит ? Стоит проверитьУ меня не рендерила... Это первое, что приходит в голову, стал бы я заморачиваться делегатами... Где-то встречал, по-моему, решение для QTableWidget, там есть вариант без QLabel (могу ошибаться, много тем перелопатил за это время), но для его предка QTableView нет такой возможности... Вообще, хотелось бы решение, которое выделяет буквы в строках представления не используя при этом виджеты... Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 13:04 И пока тему не закрыли, расскажу пару моментов. Перенес этот делегат HTML в свой проект и при "внедрении" надо учесть следующие аспекты:
1) Лучше инициализировать делегат в куче (т.е. HtmlDelegate *delegate = new HtmlDelegate;) Чтобы при выходе из модуля, где он был инициализирован и установлен для QTableView он не пропадал (иначе предаставление будет отображать пустые элементы) 2) Чтобы текст не "прилипал" к левому и правому краю ячейки в представлении необходимо в реализацию делегата (файл htmldelegate.cpp метод paint) немного подправить метод render: Код
Немного топорно, конечно, прибавлять по 5 пикселей отступ с каждой стороны, но пока ничего лучше не придумал (opt.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter - почему-то не сработало...). Название: Re: html-форматирование в QTableView Отправлено: ViTech от Май 21, 2020, 13:13 Вообще, хотелось бы решение, которое выделяет буквы в строках представления не используя при этом виджеты... Можно в исходниках посмотреть, как QLabel текст рисует. Навскидку, QLabel::paintEvent() (https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qlabel.cpp.html#_ZN6QLabel10paintEventEP11QPaintEvent). Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 13:34 И пока тему не закрыли, расскажу пару моментов. Перенес этот делегат HTML в свой проект и при "внедрении" надо учесть следующие аспекты: 1) Лучше инициализировать делегат в куче (т.е. HtmlDelegate *delegate = new HtmlDelegate;) Чтобы при выходе из модуля, где он был инициализирован и установлен для QTableView он не пропадал (иначе предаставление будет отображать пустые элементы) 2) Чтобы текст не "прилипал" к левому и правому краю ячейки в представлении необходимо в реализацию делегата (файл htmldelegate.cpp метод paint) немного подправить метод render: Код
Немного топорно, конечно, прибавлять по 5 пикселей отступ с каждой стороны, но пока ничего лучше не придумал (opt.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter - почему-то не сработало...). Методом научного тыка пришел к такой формуле (она добавляет небольшой отступ от левого края ячейки, и по вертикали получается динамика, если увеличивать/уменьшать высоту строки, то текст располагается всегда примерно по центру). Код
Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 13:37 Вообще, хотелось бы решение, которое выделяет буквы в строках представления не используя при этом виджеты... Можно в исходниках посмотреть, как QLabel текст рисует. Навскидку, QLabel::paintEvent() (https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qlabel.cpp.html#_ZN6QLabel10paintEventEP11QPaintEvent). Честно говоря столько времени "убил" на эту тему... А еще нужно сделать сохранение в разных форматах и справку... Может когда-нибудь я к этому вернусь. Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 14:13 Товарищи программисты ;D
Кое-что протестировал сейчас и оказалось... При использовании стандартного делегата представления QTableView, приложение при загрузке списка (в модель QStringListModel) размером 2 млн. строк (кириллица) использует оперативной памяти БОЛЬШЕ(!!!), чем, когда используется делегат HtmlDelegate (описанного в этой теме) :o Проверил несколько раз и вышло, что с форматированием html приложение кушает оперативы МЕНЬШЕ, чем когда подгружаешь те же списки и они отображаются в представлении с неотформатированными тегами (в первом случае заняло ~346 Мб, во втором (без HTML форматирования) - ~348 Мб). Следовательно возможность HTML-форматирования в представлении без использования QLabel теряет свою актуальность :) P.S.: тест проводился на Windows XP SP3. Именно под нее и пишется программа. Название: Re: html-форматирование в QTableView Отправлено: Пантер от Май 21, 2020, 14:15 2 MB разницы? Ты уверен, что стоит на это обращать внимание?
Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 14:24 2 MB разницы? Ты уверен, что стоит на это обращать внимание? Пантер, ты видимо не понял, я думал, что при использовании в представлении QLabel-ов будет сильно "кушаться" оперативка. И просто решил проверить на ИСХОДНЫХ списках насколько больше. Подгрузил не самые большие (всего два списка по 1 млн. строк, у меня используются де модели и два представления). А оказалось, что она, оперативка, "кушается" не больше, а МЕНЬШЕ(!!!), чем раньше, когда я использовал стандартный делегат (по умолчанию). Вообще, форматирование строк мне нужно тогда, когда их (строк) станет много меньше, как правило пару десятков, а тут выходит, что и при исходном большом их количестве памаять расходуется так же, даже меньше... Видимо это особенности реализации представлений в Qt... Название: Re: html-форматирование в QTableView Отправлено: Пантер от Май 21, 2020, 14:30 У тебя делегаты создаются только для видимых строк, так что пофиг 2 млн их или 20 штук.
Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 14:34 2 MB разницы? Ты уверен, что стоит на это обращать внимание? Поправил, мегабайты неправильно написал... Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 14:36 У тебя делегаты создаются только для видимых строк, так что пофиг 2 млн их или 20 штук. Ну, я новичок, не знал об этом. Делегаты для меня непростая тема... Название: Re: html-форматирование в QTableView Отправлено: ViTech от Май 21, 2020, 16:47 Честно говоря столько времени "убил" на эту тему... А еще нужно сделать сохранение в разных форматах и справку... Может когда-нибудь я к этому вернусь. Там может делов на: Код
Если не смущает, что в paint() каждый раз создаётся и уничтожается QLabel, то можно не заморачиваться. Но меня бы это, как минимум, насторожило. Название: Re: html-форматирование в QTableView Отправлено: tamplier от Май 21, 2020, 18:38 Честно говоря столько времени "убил" на эту тему... А еще нужно сделать сохранение в разных форматах и справку... Может когда-нибудь я к этому вернусь. Там может делов на: Код
Если не смущает, что в paint() каждый раз создаётся и уничтожается QLabel, то можно не заморачиваться. Но меня бы это, как минимум, насторожило. Ну, быстродействие не "упало", и т.к. QLabel и создается, и уничтожается, то меня это не смущает. Если приведете здесь реальный рабочий пример с методом drawItemText, то, полагаю, многие люди ищущие в сети ответ на вопрос "как форматировать текст" или "как отображать HTML-форматирование" в представлении (например в QTableView) будут Вам весьма благодарны. Название: Re: html-форматирование в QTableView Отправлено: Igors от Май 22, 2020, 10:25 Если не смущает, что в paint() каждый раз создаётся и уничтожается QLabel, то можно не заморачиваться. Но меня бы это, как минимум, насторожило. Да, это не есть хорошо. Наивное предположение: drawText рисует html, drawItemText нет. Тогда стоит попробовать просто drawText в делегате (без виджета) |