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

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

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

Offline Offline

Сообщений: 40


Просмотр профиля
« : Май 09, 2020, 18:19 »

Уважаемые форумчане!
Скажите, пожалуйста, каким образом можно "прикрутить" отображение строк с html-форматированием в QTableView?

Если упростить, то ситуация следующая (просто не знаю даже куда копать): есть список строк QStringList. Есть модель QStringListModel, которая является моделью данного списка и есть представление QTableView, которое отображает список строк (модели) с одним столбцом. Необходимо чтобы определенные буквы в представлении (в строках) отображались жирным шрифтом (либо, как-то выделялись)... Понятно, что в контексте QStringList и QStringListModel данную задачу решить не получится.
Были мысли использовать QList<QLabel *> с QAbstractListModel. Но не могу понять как это всё реализовать...
Еще как вариант использовать делегат, но с темой делегатов я на Вы, почитав книги М.Шлее и Ж.Бланшет и М.Саммерфилд, так и не разобрался с данной темой, да и как оказалось, то, что легко понимается в теории, зачастую на практике применить не получается...
Итог: реализовав бОльшую часть приложения запнулся на казалось бы пустяковой задаче.

Буду признателен любым советам по теме. Подскажите хотя бы куда копать. Использовать делегаты? Как-то прикрутить список указателей на QLabel-ы? Может QSyntaxHighlighter поможет? Или есть другой вариант, как выделить определенные буквы в списке строк в QTableView... Направьте на путь истинный...  Улыбающийся

P.S.: Может посоветуете что почитать на тему делегатов, буду очень признателен.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Использовать делегаты? Как-то прикрутить список указателей на QLabel-ы?
А если просто в методе модели data (DisplayRole) формировать нужную html строку из исходной?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


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

Используй делегаты, это именно то, что тебе нужно.
Записан

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

Offline Offline

Сообщений: 40


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

Использовать делегаты? Как-то прикрутить список указателей на QLabel-ы?
А если просто в методе модели data (DisplayRole) формировать нужную html строку из исходной?

Было бы замечательно, но метод возвращает тип QVariant и к типу QLabel его не приведешь (чтобы отображать в представлении текст отформатированный в стиле html).
Записан
tamplier
Новичок

Offline Offline

Сообщений: 40


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

Спасибо большое за подсказки!
Решил проблему следующим способом (может кому пригодится):

delegate.h:
Код
C++ (Qt)
#ifndef DELEGATE_H
#define DELEGATE_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
 

delegate.cpp:
Код
C++ (Qt)
#include "delegate.h"
 
#include <QtWidgets>
 
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();
 
QTextDocument doc(opt.text);
 
doc.setHtml(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.drawContents(painter, clip);
 
painter->restore();
}
 

main.cpp:
Код
C++ (Qt)
#include "delegate.h"
#include <QApplication>
#include <QtWidgets>
 
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
 
QStringListModel model;
QTableView tableView;
 
QStringList lst;
lst << "<b>Bold text.</b> Custom text." << "It's <font color=red><b>red</b></font> text. <i>Italic</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();
}
 

Честно признаюсь решением не доволен... Хоть и списки для форматированного вывода в итоге должны быть небольшими, всё-равно не хочется элементами представления делать такие "тяжелые" виджеты, как QTextDocument... Но так и не придумал, как "прикрутить" к модели QTableView виджет QLabel. В сети и в справке ничего вразумительного так и не нашел, может плохо искал...
« Последнее редактирование: Май 20, 2020, 21:13 от tamplier » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


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

Я помню, когда-то свой делегат чекбокса писал. Поищи, должна быть возможность QLabel заюзать.

https://www.qtcentre.org/threads/30594-QItemDelegate-with-QLabel-for-QTableView
Записан

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

Offline Offline

Сообщений: 40


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

Да, пробовал подобный вариант. Но переопределение методов createEditor и setEditorData предполагает, что будет редактирование модели через представление. В моем случае этого не надо. И если реализовать свой делегат подобным образом, то текст в представлении отображается некорректно, виджет QLabel как-бы накладывается на текст (происходит дублирование).

В моем случае это выглядит так:



Код следующий:

delegate.h:
Код
C++ (Qt)
#ifndef DELEGATE_H
#define DELEGATE_H
 
#include <QStyledItemDelegate>
 
class HtmlDelegate : public QStyledItemDelegate
{
   Q_OBJECT
 
public:
HtmlDelegate(QObject *parent = 0);
 
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
 
void setEditorData(QWidget* editor, const QModelIndex& index) const;
};
 
#endif
 

delegate.cpp:
Код
C++ (Qt)
#include "delegate.h"
 
#include <QtWidgets>
 
HtmlDelegate::HtmlDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
}
 
 
QWidget* HtmlDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex&) const
{
QLabel* label = new QLabel(parent);
 
return label;
}
 
void HtmlDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
QString value = index.model()->data(index, Qt::DisplayRole).toString();
 
QLabel* label = static_cast<QLabel*>(editor);
 
label->setText(value);
}
 
 

main.cpp:
Код
C++ (Qt)
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
 
QStringListModel model;
QTableView tableView;
 
QStringList lst;
 
lst << "<b>First</b> html text" << "Second 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();
for(int i=0; i<lst.count(); ++i) {
tableView.openPersistentEditor(model.index(i)); // view delegate all time
}
 
return app.exec();
}
 
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


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

А куда ты дел все, что связано с QStyleOptionViewItem? Ты же должен не только создать виджет, но и корректно его разместить.
Записан

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

Offline Offline

Сообщений: 40


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

А куда ты дел все, что связано с QStyleOptionViewItem? Ты же должен не только создать виджет, но и корректно его разместить.

Уважаемый Пантер, не очень понимаю, что ты имеешь ввиду... Хотя бы пару строчек кода, или ссылку на пример... Куда и как именно я должен разместить "все, что связано с QStyleOptionViewItem"?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


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

tamplier, у тебя же выше был код HtmlDelegate::paint. Для QLabel тоже нужно реализовать этот метод и правильно разместить виджет.
Записан

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

Offline Offline

Сообщений: 40


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

tamplier, у тебя же выше был код HtmlDelegate::paint. Для QLabel тоже нужно реализовать этот метод и правильно разместить виджет.

Да. Я понимаю, что это логично, именно метод paint использовать для отображения QLabel в представлении... Но у меня затык в том, что QLabel не содержит метод drawContents, и аналогичного я не нашел. Не могу понять как отрисовать виджет QLabel в итеме...  Обеспокоенный
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


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

https://doc.qt.io/qt-5/qwidget.html#grab
https://doc.qt.io/qt-5/qwidget.html#render
Может, куда-то сюда покопать...
« Последнее редактирование: Май 21, 2020, 10:20 от Пантер » Записан

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

Сообщений: 11445


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

Было бы замечательно, но метод возвращает тип QVariant и к типу QLabel его не приведешь (чтобы отображать в представлении текст отформатированный в стиле html).
А просто QString в html?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


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

Было бы замечательно, но метод возвращает тип QVariant и к типу QLabel его не приведешь (чтобы отображать в представлении текст отформатированный в стиле html).
А просто QString в html?
QLabel нужен для рендеринга.
Записан

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

Сообщений: 858



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

Не могу понять как отрисовать виджет QLabel в итеме...  Обеспокоенный

QAbstractItemView::setIndexWidget пробовали?
Записан

Пока сам не сделаешь...
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


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