becks
@becks

Qt Html Delegate для QTableView?

Нужно в ячейках таблицы QTableView показывать html текст.
Главные требования:
1) Текст масштабируется под размеры ячейки, а не размещается весь на одной строке.
2) В тексте будут ссылки нужна реакция по клику на ссылку - запустить некоторый слот.
3) Можно выделять отдельные части текста, для дальнейшего копирования куда-нибудь. Редактирование\правка элемента в принципе не нужны.

Исходя из второго пункта делегат решил делать на основе QTextBrowser, поскольку поддерживает реакцию на клик по ссылке - anchorClicked.
Дальше возникает дилемма отнаследоваться от QItemDelegate или от QStyledItemDelegate. Первый вариант проще, поскольку поддерживаются стандартные виджеты.
Пробовал и первый и второй ничего не получается, кучу времени убил. Выложу сюда вариант №2 (отнаследоваться от QStyledItemDelegate). Если кому нужно будет могу и первый вариант выложить.

HtmlDelegate.h
#pragma once
#include <QStyledItemDelegate>
class HtmlDelegate : public QStyledItemDelegate
{
public:
    HtmlDelegate(QObject *parent=0) : QStyledItemDelegate(parent)
    {}
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

HtmlDelegate.cpp
#include <QPainter>
#include <QTextDocument>
#include "HTMLDelegate.h"
void HtmlDelegate::paint(QPainter* painter, const QStyleOptionViewItem & option, const QModelIndex &index) const
{
    QStyleOptionViewItemV4 options = option;
    initStyleOption(&options, index);
    painter->save();
    QTextBrowser browser;
    QFont font = browser.document()->defaultFont();
    font.setPixelSize(18);
    browser.document()->setDefaultFont(font);
    browser.setHtml(options.text);
    options.text = index.model()->data(index, Qt::DisplayRole).toString();
    options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter);
    painter->translate(options.rect.left(), options.rect.top());
    QRect clip(0, 0, options.rect.width(), options.rect.height());
    browser.document()->drawContents(painter, clip);
    painter->restore();
}
QSize HtmlDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
    QStyleOptionViewItemV4 options = option;
    initStyleOption(&options, index);
    QTextBrowser browser;
    browser.setHtml(options.text);
    browser.document()->setTextWidth(options.rect.width());
    return QSize(doc.idealWidth(), browser.document()->size().height());
}


Проверял на QTableWidget ставил ему для колонки QTextBrowser, все отображается и работает отлично, т.е. проблемы у меня.
  • Вопрос задан
  • 5504 просмотра
Пригласить эксперта
Ответы на вопрос 1
@tugo
Я сделал вариант, насколько я понял вашу задачу.
1. В делегате показываю в качестве редактора QLabel.
1а. Можно сделать перенос по словам wordWrap.
2. Вид настраиваю на постоянный показ редактора
tableView.openPersistentEditor(index);
3. В QLable делаю гиперссылку
4. Настраиваюсь на сигнал void QLabel::linkActivated(const QString & link). Этот пункт я не сделал, вроде должен работать.

Вот страшненький пример, смысл будет понятен.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы