crossplatform.ru

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


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

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

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


Последние 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();
    }
}
Прикрепленное изображение

Если нужен больший функционал от заголовков, смотри в исходники 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 Текстовая версия Сейчас: 28.3.2024, 19:55