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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Html text in QButton  (Прочитано 6970 раз)
fear
Гость
« : Октябрь 16, 2008, 17:25 »

QButton с текстом html, по аналогии с QLabel, как реализовать или есть готовое решение?
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #1 : Октябрь 16, 2008, 18:17 »

ищи по форуму, это уже было
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
fear
Гость
« Ответ #2 : Октябрь 17, 2008, 16:15 »

ищи по форуму, это уже было
Если речь про эту тему, то полностью вопрос в ней не раскрыли. Метод paintEvent() переопределять таким образом неправильно, потому что приводит к некорректной работе кнопки, не отрисовывается изображение, кнопка неправильно перерисовывается при событиях.

Цитата: pastor
Код:
class HTMLButton: public QPushButton {
    Q_OBJECT
public:
    HTMLButton(QWidget *parent = 0) : QPushButton(parent) {
        init();
    }

HTMLButton(const QString &text, QWidget *parent = 0) : QPushButton(text, parent) {
        init();
    }

protected:
virtual void paintEvent ( QPaintEvent *event )  {
QPainter painter(this);
QStyleOptionButton styleOps;
styleOps.initFrom(this);
styleOps.state = isDown() ? QStyle::State_Sunken : QStyle::State_Raised;
if (isDefault())
styleOps.features |= QStyleOptionButton::DefaultButton;
style()->drawControl(QStyle::CE_PushButton, &styleOps, &painter, this);

QAbstractTextDocumentLayout::PaintContext ctx;
ctx.palette = palette();
                       doc->setHtml(text());
doc->documentLayout()->draw(&painter, ctx);
}

private:
void init() {
doc = new QTextDocument(this);
}

private:
QTextDocument *doc;
};


Правильный путь - переопределение метода QStyle::drawControl() для CE_PushButtonLabel. Но как определить размер области необходимой для отрисовки html-текста? QTextDocument::pageSize()? Почему этот метод возвращает QSizeF, а не QSize? Может кто-нибуть поделится инфой по теме?
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #3 : Октябрь 17, 2008, 17:45 »

Переопределение paintEvent вполне корректное решение. Я привел минимальный функционал, далее допиливате уж вы. Копайте класс QStyleOptionButton, устанавливайте иконки и все остальное
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
ритт
Гость
« Ответ #4 : Октябрь 17, 2008, 20:17 »

в данном случае переопределение метода QStyle::drawControl() для CE_PushButtonLabel - неправильный путь, т.к. речь идёт о виджете, а не о стиле!
Записан
fear
Гость
« Ответ #5 : Октябрь 20, 2008, 11:18 »

в данном случае переопределение метода QStyle::drawControl() для CE_PushButtonLabel - неправильный путь, т.к. речь идёт о виджете, а не о стиле!
На чем основано это утверждение? Если посмотреть реализацию QPushButton, то отрисовка контента (текст + иконка) происходит именно в стиле... И в этом есть логика, так как на каждой из платформ кнопка должна отрисовываться по своему, в своем стиле.
Записан
ритт
Гость
« Ответ #6 : Октябрь 20, 2008, 11:41 »

и?
в каком стиле кнопка QButton отрисовывается с текстом в формате html ? ото ж...

стиль рисует кнопку, мы рисуем на кнопке - все довольны.
если под "стилем" подразумевается такой стиль, который будет устанавливаться непосредственно кнопке, тролли называет такой подход "прокси-стилем" (proxy-style)

в любом случае, пока не появится стандартных кнопок, поддерживающих форматирование хтмл, парсить текст в styleoption'е чтобы потом прогнать через рендерер хтмл и отрисовать на баттоне нелогично. стоит сменить стиль приложения - на кнопке будет хтмльный "мусор"...
Записан
fear
Гость
« Ответ #7 : Октябрь 20, 2008, 14:35 »

и?
в каком стиле кнопка QButton отрисовывается с текстом в формате html ? ото ж...
Если бы кнопка отрисовывалась с текстом в формате html, не было бы этой темы

стиль рисует кнопку, мы рисуем на кнопке - все довольны.
Не понял смысловой нагрузки этого предложения, если фразой 'мы рисуем на кнопке' вы хотели сказать что контент кнопки QPushButton рисуется в методе paintEvent(), то это не правда, если посмотреть исходный код библиотеки, видно что кнопка рисуется от начала до конца в стиле
Код
void QPushButton::paintEvent(QPaintEvent *)
{
   QStylePainter p(this);
   QStyleOptionButton option;
   initStyleOption(&option);
   p.drawControl(QStyle::CE_PushButton, option);
}
Код
case CE_PushButtonLabel:
       if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
           QRect textRect = button->rect;
           uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
           if (!styleHint(SH_UnderlineShortcut, button, widget))
               tf |= Qt::TextHideMnemonic;
 
           if (!button->icon.isNull()) {
               //Center both icon and text
               QRect iconRect;
               QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
               if (mode == QIcon::Normal && button->state & State_HasFocus)
                   mode = QIcon::Active;
               QIcon::State state = QIcon::Off;
               if (button->state & State_On)
                   state = QIcon::On;
 
               QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
               int labelWidth = pixmap.width();
               int labelHeight = pixmap.height();
               int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
               int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
               if (!button->text.isEmpty())
                   labelWidth += (textWidth + iconSpacing);
 
               iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
                                textRect.y() + (textRect.height() - labelHeight) / 2,
                                pixmap.width(), pixmap.height());
 
               iconRect = visualRect(button->direction, textRect, iconRect);
 
               tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
 
               if (button->direction == Qt::RightToLeft)
                   textRect.setRight(iconRect.left() - iconSpacing);
               else
                   textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing);
 
               if (button->state & (State_On | State_Sunken))
                   iconRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
                                      pixelMetric(PM_ButtonShiftVertical, opt, widget));
               p->drawPixmap(iconRect, pixmap);
           } else {
               tf |= Qt::AlignHCenter;
           }
           if (button->state & (State_On | State_Sunken))
               textRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
                            pixelMetric(PM_ButtonShiftVertical, opt, widget));
 
           if (button->features & QStyleOptionButton::HasMenu) {
               int indicatorSize = pixelMetric(PM_MenuButtonIndicator, button, widget);
               if (button->direction == Qt::LeftToRight)
                   textRect = textRect.adjusted(0, 0, -indicatorSize, 0);
               else
                   textRect = textRect.adjusted(indicatorSize, 0, 0, 0);
           }
           drawItemText(p, textRect, tf, button->palette, (button->state & State_Enabled),
                        button->text, QPalette::ButtonText);
       }
       break;

если под "стилем" подразумевается такой стиль, который будет устанавливаться непосредственно кнопке, тролли называет такой подход "прокси-стилем" (proxy-style)
Вы что-то путаете, концепция прокси-стиля позволяет определить единый стиль для всех платформ. Стиль может быть установлен как определенному виджету, так и приложению в целом. Говоря о стиле я имею в виду класс QStyle.

в любом случае, пока не появится стандартных кнопок, поддерживающих форматирование хтмл, парсить текст в styleoption'е чтобы потом прогнать через рендерер хтмл и отрисовать на баттоне нелогично. стоит сменить стиль приложения - на кнопке будет хтмльный "мусор"...
Что мешает сделать 'стандартную' кнопку самостоятельно? Для начала мне кажется стоит рассмотреть ситуацию с одним стилем, не забегая далеко вперед, изменение стиля требуется далеко не каждому приложению.
Записан
ритт
Гость
« Ответ #8 : Октябрь 20, 2008, 15:02 »

ррр...

p.drawControl(QStyle::CE_PushButton, option) рисует контрол (кнопку)...
перед отрисовкой отнимаем у QStyleOptionButton содержимое text, парсим этот текст, рендерим и рисуем поверх нарисованной кнопки в определённых координатах - что-нть вроде p.drawText(...)/p.drawPixmap(...) и т.п.
в итоге получаем виджет - самодостаточный и не зависящий от какого бы то ни было стиля.

а концепция прокси-стиля позволяет внести некритичные изменения в любой стиль, не прикасаясь при этом к коду самого стиля. в аттаче пример такого прокси-стиля.

> Что мешает сделать 'стандартную' кнопку самостоятельно?
самостоятельно созданный виджет будет уже кастомным, а стандарт в данном случае задают тролли Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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