Russian Qt Forum
Март 29, 2024, 08:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: html-форматирование в QTableView  (Прочитано 12169 раз)
tamplier
Новичок

Offline Offline

Сообщений: 40


Просмотр профиля
« Ответ #15 : Май 21, 2020, 11:33 »


Спасибо ОГРОМНОЕ! Очень помог!
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #16 : Май 21, 2020, 11:42 »


Спасибо ОГРОМНОЕ! Очень помог!
Не забудь сюда запостить код рабочего решения.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
tamplier
Новичок

Offline Offline

Сообщений: 40


Просмотр профиля
« Ответ #17 : Май 21, 2020, 11:46 »

Благодаря тому, что Пантер дал мне правильную подсказку (указал на нужный метод), получилось следующее:

htmldelegat.h
Код
C++ (Qt)
#ifndef HTMLDELEGATE_H
#define HTMLDELEGATE_H
 
#include <QStyledItemDelegate>
 
class HtmlDelegate : public QStyledItemDelegate
{
   Q_OBJECT
 
public:
   HtmlDelegate(QObject *parent = 0);
 
   void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
 
#endif
 

htmldelegat.cpp
Код
C++ (Qt)
#include <QtWidgets>
#include "htmldelegate.h"
 
HtmlDelegate::HtmlDelegate(QObject *parent)
   : QStyledItemDelegate(parent)
{
}
 
void HtmlDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
   QStyleOptionViewItem opt = option;
   initStyleOption(&opt, index);
 
   painter->save();
 
   QLabel doc(opt.text);
 
   doc.setText(opt.text);
 
   opt.text = "";
   opt.widget->style()->drawControl(QStyle::CE_ItemViewItem, &option, painter);
 
   painter->translate(opt.rect.left(), opt.rect.top());
   QRect clip(0, 0, opt.rect.width(), opt.rect.height());
 
   doc.render(painter, QPoint(0,0), QRegion(QRect(clip)), QWidget::DrawChildren); // !!!!!
 
   painter->restore();
}
 

main.cpp
Код
C++ (Qt)
#include "htmldelegate.h"
#include <QApplication>
#include <QtWidgets>
 
int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
 
   QStringListModel model;
   QTableView tableView;
 
   QStringList lst;
 
   lst << "<b>First</b> html text"
       << "Se<font color=red>con</font>d html <i>text</i>";
 
   model.setStringList(lst);
   tableView.setModel(&model);
 
   HtmlDelegate delegate;
   tableView.setItemDelegate(&delegate);
   tableView.setEditTriggers(QAbstractItemView::NoEditTriggers);
 
   tableView.setWindowTitle("Html delegate");
   tableView.show();
   tableView.resizeColumnsToContents();
 
   return app.exec();
}
 
Записан
tamplier
Новичок

Offline Offline

Сообщений: 40


Просмотр профиля
« Ответ #18 : Май 21, 2020, 11:48 »

Наверное это единственный форум, где решена проблема отображения QLabel в QTableView  Улыбающийся. Тему можно закрывать.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #19 : Май 21, 2020, 11:54 »

Отлично! Пусть теперь кешируется в поисковиках. Улыбающийся
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #20 : Май 21, 2020, 12:12 »

QLabel нужен для рендеринга.
А нужен ли? Если просто так дать таблице/ячейке html строку, она что, эту строку не отрендерит ?  Стоит проверить
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #21 : Май 21, 2020, 12:43 »

QLabel нужен для рендеринга.
А нужен ли? Если просто так дать таблице/ячейке html строку, она что, эту строку не отрендерит ?  Стоит проверить
Нет, не отрендерит. Иначе не предлагали бы делегаты.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
tamplier
Новичок

Offline Offline

Сообщений: 40


Просмотр профиля
« Ответ #22 : Май 21, 2020, 12:44 »

QLabel нужен для рендеринга.
А нужен ли? Если просто так дать таблице/ячейке html строку, она что, эту строку не отрендерит ?  Стоит проверить

У меня не рендерила... Это первое, что приходит в голову, стал бы я заморачиваться делегатами... Где-то встречал, по-моему, решение для QTableWidget, там есть вариант без QLabel (могу ошибаться, много тем перелопатил за это время), но для его предка QTableView нет такой возможности...

Вообще, хотелось бы решение, которое выделяет буквы в строках представления не используя при этом виджеты...
Записан
tamplier
Новичок

Offline Offline

Сообщений: 40


Просмотр профиля
« Ответ #23 : Май 21, 2020, 13:04 »

И пока тему не закрыли, расскажу пару моментов. Перенес этот делегат HTML в свой проект и при "внедрении" надо учесть следующие аспекты:
1) Лучше инициализировать делегат в куче (т.е. HtmlDelegate *delegate = new HtmlDelegate;) Чтобы при выходе из модуля, где он был инициализирован и установлен для QTableView он не пропадал (иначе предаставление будет отображать пустые элементы)
2) Чтобы текст не "прилипал" к левому и правому краю ячейки в представлении необходимо в реализацию делегата (файл htmldelegate.cpp метод paint) немного подправить метод render:

Код
C++ (Qt)
//............
painter->translate(opt.rect.left(), opt.rect.top());
QRect clip(0, 0, opt.rect.width(), opt.rect.height());
 
lbl.render(painter, QPoint(5,5), QRegion(QRect(clip)), QWidget::DrawChildren); // QPoint(5,5)
//.........
 

Немного топорно, конечно, прибавлять по 5 пикселей отступ с каждой стороны, но пока ничего лучше не придумал (opt.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter - почему-то не сработало...).
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #24 : Май 21, 2020, 13:13 »

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

Можно в исходниках посмотреть, как QLabel текст рисует. Навскидку, QLabel::paintEvent().
Записан

Пока сам не сделаешь...
tamplier
Новичок

Offline Offline

Сообщений: 40


Просмотр профиля
« Ответ #25 : Май 21, 2020, 13:34 »

И пока тему не закрыли, расскажу пару моментов. Перенес этот делегат HTML в свой проект и при "внедрении" надо учесть следующие аспекты:
1) Лучше инициализировать делегат в куче (т.е. HtmlDelegate *delegate = new HtmlDelegate;) Чтобы при выходе из модуля, где он был инициализирован и установлен для QTableView он не пропадал (иначе предаставление будет отображать пустые элементы)
2) Чтобы текст не "прилипал" к левому и правому краю ячейки в представлении необходимо в реализацию делегата (файл htmldelegate.cpp метод paint) немного подправить метод render:

Код
C++ (Qt)
//............
painter->translate(opt.rect.left(), opt.rect.top());
QRect clip(0, 0, opt.rect.width(), opt.rect.height());
 
lbl.render(painter, QPoint(5,5), QRegion(QRect(clip)), QWidget::DrawChildren); // QPoint(5,5)
//.........
 

Немного топорно, конечно, прибавлять по 5 пикселей отступ с каждой стороны, но пока ничего лучше не придумал (opt.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter - почему-то не сработало...).


Методом научного тыка пришел к такой формуле (она добавляет небольшой отступ от левого края ячейки, и по вертикали получается динамика, если увеличивать/уменьшать высоту строки, то текст располагается всегда примерно по центру).

Код
C++ (Qt)
lbl.render(painter, QPoint(5,opt.rect.height()/2 - 7), QRegion(QRect(clip)), QWidget::DrawChildren);
 
Записан
tamplier
Новичок

Offline Offline

Сообщений: 40


Просмотр профиля
« Ответ #26 : Май 21, 2020, 13:37 »

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

Можно в исходниках посмотреть, как QLabel текст рисует. Навскидку, QLabel::paintEvent().

Честно говоря столько времени "убил" на эту тему... А еще нужно сделать сохранение в разных форматах и справку... Может когда-нибудь я к этому вернусь.
Записан
tamplier
Новичок

Offline Offline

Сообщений: 40


Просмотр профиля
« Ответ #27 : Май 21, 2020, 14:13 »

Товарищи программисты  Смеющийся
Кое-что протестировал сейчас и оказалось...
При использовании стандартного делегата представления QTableView, приложение при загрузке списка (в модель QStringListModel) размером 2 млн. строк (кириллица) использует оперативной памяти БОЛЬШЕ(!!!), чем, когда используется делегат HtmlDelegate (описанного в этой теме)   Шокированный
Проверил несколько раз и вышло, что с форматированием html приложение кушает оперативы МЕНЬШЕ, чем когда подгружаешь те же списки и они отображаются в представлении с неотформатированными тегами (в первом случае заняло ~346 Мб, во втором (без HTML форматирования) - ~348 Мб).
Следовательно возможность HTML-форматирования в представлении без использования QLabel теряет свою актуальность  Улыбающийся

P.S.: тест проводился на Windows XP SP3. Именно под нее и пишется программа.
« Последнее редактирование: Май 21, 2020, 14:33 от tamplier » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #28 : Май 21, 2020, 14:15 »

2 MB разницы? Ты уверен, что стоит на это обращать внимание?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
tamplier
Новичок

Offline Offline

Сообщений: 40


Просмотр профиля
« Ответ #29 : Май 21, 2020, 14:24 »

2 MB разницы? Ты уверен, что стоит на это обращать внимание?

Пантер, ты видимо не понял, я думал, что при использовании в представлении QLabel-ов будет сильно "кушаться" оперативка. И просто решил проверить на ИСХОДНЫХ списках насколько больше. Подгрузил не самые большие (всего два списка по 1 млн. строк, у меня используются де модели и два представления). А оказалось, что она, оперативка, "кушается" не больше, а МЕНЬШЕ(!!!), чем раньше, когда я использовал стандартный делегат (по умолчанию). Вообще, форматирование строк мне нужно тогда, когда их (строк) станет много меньше, как правило пару десятков, а тут выходит, что и при исходном большом их количестве памаять расходуется так же, даже меньше...

Видимо это особенности реализации представлений в Qt...
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.166 секунд. Запросов: 23.