crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в Delegate 2 - HtmlDelegate
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
Теги
Выровнять по центру
Ссылка на тему
Ссылка на сообщение
Скрытый текст
Сокращение
Код с подсветкой
Offtopic
 
Удалить форматирование
Спец. элементы
Шрифт
Размер
 
Цвет шрифта
 
Отменить ввод
Вернуть ввод
Полужирный
Курсив
Подчеркнутый
 
 
Смайлики
Вставить изображение
Вставить адрес электронной почты
Цитата
Код
Раскрывающийся текст
 
Увеличить отступ
По левому краю
По центру
По правому краю
Вставить список
Вставить список

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
igor_bogomolov Дата 3.12.2010, 8:42
 
Цитата(Obey-Kun @ 3.12.2010, 0:31) *
ты там метод layoutRect используешь... что это?
Смотри 4 сообщение темы. Это функция которую я писал для выравнивания текста в ячейке. Написана она конечно коряво, но это не главное. Кому надо адаптирует
Цитата(Obey-Kun @ 3.12.2010, 1:15) *
Кстати, насчёт изначального вопроса темы. Вот более короткое (и менее полное) решение: http://developer.qt.nokia.com/faq/answer/h...n_my_qtableview
Решение идентичное нашему. Да и сложно придумать что то иное. Сам когда то это решение подсмотрел в исходниках QLabel. К стати, в исходники рекомендую по чаще заглядывать, там можно на многие вопросы ответ найти.

Цитата(Obey-Kun @ 3.12.2010, 1:15) *
Не получится, так как в оригинальном методе прорисовки используются некоторые приватные методы.
Ну так можно код этих приватных методов позаимствовать.
А какой функционал не удалось поддержать?
Obey-Kun Дата 3.12.2010, 1:15
  Да уж, при насследовании, оказывается, не удастся восстановить все фичи QHeaderView. Например, учитывать позицию мыши при отрисовке (в некоторых стилях она учитывается). Не получится, так как в оригинальном методе прорисовки используются некоторые приватные методы.
Пока решил повременить с рендеринг rich text у себя в программе. Заодно проголосовал за баг Qt: 2380.

Кстати, насчёт изначального вопроса темы. Вот более короткое (и менее полное) решение: http://developer.qt.nokia.com/faq/answer/h...n_my_qtableview
Obey-Kun Дата 3.12.2010, 0:31
  спасибо! правда, решение с фильтром не прокатило, ибо используются защищённые методы, пришлось унаследовать.
ты там метод layoutRect используешь... что это? компилятор ругается на его отсутствие, в документации не нашёл...
igor_bogomolov Дата 3.12.2010, 0:10
  фильтр нужно устанавливать для viewport заголовка

m_table_view->horizontalHeader()->viewport()->installEventFilter(this);
Obey-Kun Дата 2.12.2010, 23:35
  Что я делаю не так? В конструкторе делаю
m_table_view->horizontalHeader()->installEventFilter(this);


И делаю метод
bool SoilsWidget::eventFilter(QObject *watched, QEvent *event)
{
    if ( event->type() == QEvent::Paint ) {
        qDebug() << watched << event;
        return true;
    } else {
        return QWidget::eventFilter(watched, event);
    }
}


И ничего. Ничего в консоль не выводится. Хедер рисуется как ни в чём не бывало.

p.s.: блин, наверное надо было новую тему создать, но уже поздно, это сообщение я не могу удалить.
Obey-Kun Дата 2.12.2010, 23:00
  Спасибо! Только сделаю это с помощью eventFilter, дабы лишний раз не наследовать.
Кстати, с твоим подходом было бы логичнее использовать QHeaderView::paintSection.
igor_bogomolov Дата 1.12.2010, 10:34
 
Цитата(Obey-Kun @ 1.12.2010, 6:49) *
А аналогично QHeaderView модешь переделать?
Если упрощенно, то так.
Раскрывающийся текст
void Header::paintEvent(QPaintEvent *e)
{
    if (!count()) return;

    QPainter painter(viewport());
    QRect currentSectionRect;
    const int height = viewport()->height();
    for (int i = 0; i != model()->columnCount(); ++i) {
        painter.save();
        currentSectionRect.setRect(sectionViewportPosition(i), 0, sectionSize(i), height);

        QStyleOptionHeader opt;
        initStyleOption(&opt);

        opt.rect = currentSectionRect;
        opt.section = i;
        style()->drawControl(QStyle::CE_HeaderSection, &opt, &painter, this);


        QString str = model()->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString();

        QTextDocument td;
        td.setHtml(str);
        QRectF lr = layoutRect(td, currentSectionRect);
        painter.translate(lr.topLeft());
        painter.setClipRect(lr.translated(-lr.x(), -lr.y()));
        td.drawContents(&painter, QRectF());

        painter.restore();
    }
}
 Р В Р в‚¬Р В РЎВ˜Р В Р’µР Р…ьшено Р Т‘Р С• 21%
Прикрепленное изображение
335 x 157 (9.93 килобайт)

Если нужен больший функционал от заголовков, смотри в исходники QHeaderView
Obey-Kun Дата 1.12.2010, 6:49
 
Цитата(igor_bogomolov @ 14.4.2009, 0:07) *
jim1406, с тебя пиво :drinks:
Шучу. :D
Интересную ты задачку задал, если честно не сразу справился. Но было очень интерестно повозиться, т.ч. спасибо.
В архиве готовый делегат, с тестовым примером. Обрати внимание на параметр Qt::Alignment align, который передается в конструкторе, он позволяет ориентировать текст в ячейке.

Раскрывающийся текст
#include <QtGui>
#include "htmltextdelegate.h"

void HtmlDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                         const QModelIndex &index) const
{
    QString str = index.data(Qt::DisplayRole).toString();
    QTextDocument td;
    td.setHtml(str);

    QStyleOptionViewItem opt = option;
    QRectF lr = layoutRect(td, opt.rect);

    painter->save();
    painter->translate(lr.topLeft());
    painter->setClipRect(lr.translated(-lr.x(), -lr.y()));
    td.drawContents(painter, QRectF());
    painter->restore();
}

QWidget *HtmlDelegate::createEditor(QWidget *parent,
                                    const QStyleOptionViewItem &option,
                                    const QModelIndex &index) const
{
    QTextEdit *textEdit = new QTextEdit(parent);
    return textEdit;
}

void HtmlDelegate::setEditorData(QWidget *editor,
                                 const QModelIndex &index) const
{
    QString str = index.data(Qt::DisplayRole).toString();
    QTextEdit *textEdit = qobject_cast<QTextEdit*>(editor);
    textEdit->setHtml(str);
}

void HtmlDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                const QModelIndex &index) const
{
    QTextEdit *textEdit = qobject_cast<QTextEdit*>(editor);
    QString str = textEdit->toHtml();
    model->setData(index, str, Qt::DisplayRole);
}


QRectF HtmlDelegate::layoutRect(const QTextDocument & td, QRect rect) const
{
    QRectF rectf;
    qreal xo;
    qreal yo;

    if(align & Qt::AlignLeft) {
        xo = 0;
    } else if(align & Qt::AlignRight) {
        qreal rw = td.documentLayout()->documentSize().width();
        xo = 0;
        xo = qMax((rect.width()-rw), qreal(0));
    } else if(align & Qt::AlignHCenter) {
        qreal rw = td.documentLayout()->documentSize().width();
        xo = 0;
        xo = qMax((rect.width()-rw)/2, qreal(0));
    }

    if(align & Qt::AlignTop) {
        yo = 0;
    } else if(align & Qt::AlignBottom) {
        qreal rh = td.documentLayout()->documentSize().height();
        yo = 0;
        yo = qMax((rect.height()-rh), qreal(0));
    } else if(align & Qt::AlignVCenter) {
        qreal rh = td.documentLayout()->documentSize().height();
        yo = 0;
        yo = qMax((rect.height()-rh)/2, qreal(0));
    }
    return QRectF(xo + rect.x(), yo + rect.y(), rect.width(), rect.height());
}


Красавчик. А аналогично QHeaderView модешь переделать? Только там оно уже не делегаты использует, а само рисует.
dezconnect Дата 24.10.2010, 14:30
 
Цитата(dezconnect @ 20.5.2010, 15:44) *
Цитата(Litkevich Yuriy @ 19.5.2010, 19:12) *
Цитата(dezconnect @ 19.5.2010, 17:43) *
макрос Q_D
этот макрос всего лишь объявляет личные (внутренние) данные. Т.е. запись:
Q_D(SomeClass)
d->someFunc();

означает:
SomeClassPrivate *const d = d_func(); // получает указатель на внутренние данные
d->someFunc();
следовательно смотри соответствующий метод этого внутреннего класса (обычно этот класс описан раньше основного)



ммм, вообще в QTextDocument есть такая фича как setTextWidth() =) помогло =)

продолжаю копания в сторону sizeHint() ... если в paint() передается painter и ессесно по нему можно узнать ширину TableView через painter->window.width(), то в sizeHint такого счастья не наблюдаю ... Может кто сталкивался...

и что ловить если у меня моделью является QSqlQueryModel и для первых 256 записей, sizeHint отрабатывает корректно, после "дозагрузки" данных, они все ломятся высотой в 22 пиксела =( это куда копять опять же...


Трабла с дозагрузкой данных в TableView из модели актуален по прежнему
dezconnect Дата 20.5.2010, 10:44
 
Цитата(Litkevich Yuriy @ 19.5.2010, 19:12) *
Цитата(dezconnect @ 19.5.2010, 17:43) *
макрос Q_D
этот макрос всего лишь объявляет личные (внутренние) данные. Т.е. запись:
Q_D(SomeClass)
d->someFunc();

означает:
SomeClassPrivate *const d = d_func(); // получает указатель на внутренние данные
d->someFunc();
следовательно смотри соответствующий метод этого внутреннего класса (обычно этот класс описан раньше основного)



ммм, вообще в QTextDocument есть такая фича как setTextWidth() =) помогло =)

продолжаю копания в сторону sizeHint() ... если в paint() передается painter и ессесно по нему можно узнать ширину TableView через painter->window.width(), то в sizeHint такого счастья не наблюдаю ... Может кто сталкивался...

и что ловить если у меня моделью является QSqlQueryModel и для первых 256 записей, sizeHint отрабатывает корректно, после "дозагрузки" данных, они все ломятся высотой в 22 пиксела =( это куда копять опять же...
Просмотр темы полностью (откроется в новом окне)
RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 10.7.2025, 11:56