Всем привет!
вот тут http://www.forum.crossplatform.ru/index.php?showtopic=4154 Litkevich Yuriy выложил пример AeroButton. В программе сделал кнопки примерно также. Но чтука в том что под виндой эти кнопки получаются с идеально на мой взгляд ровными обводами засчет антиалайзинга.. А вот под линуксом они ужасны. Вычитал, что в иксах нужно для достижения такого же результат включить какую-то опцию отрисовки. Но есть универсальный способ: рисование на QImage (т.е. как бы использование его движка, а не "движка" ОС). Вот делаю как в книге написано =)
void CRoundButton::paintEvent(QPaintEvent *pEvent)
{
QImage oImage(this->size(), QImage::Format_ARGB32_Premultiplied);
QPainter oImagePainter(&oImage);
oImagePainter.initFrom(this);
oImagePainter.setRenderHint(QPainter::Antialiasing, true);
oImagePainter.eraseRect(this->rect());
//тут отрисовка по сути таже что и в примере aerobutton (только на oImagePainter)
//и потом
oImagePainter.end();
QPainter oWidgetPainter(this);
oWidgetPainter.drawImage(0, 0, oImage);
Rocky, а ты про painter.setOpacity не забыл?
неа (( в том-то и дело что не забыл
Rocky, ты можешь выложить код AeroButton модифицированный под QImage?
Вот:
void CRoundButton::paintEvent(QPaintEvent *pEvent)
{
Q_UNUSED(pEvent);
QImage oImage(this->size(), QImage::Format_ARGB32_Premultiplied);
QPainter oImagePainter(&oImage);
//oImagePainter.setCompositionMode(QPainter::CompositionMode_Xor); //это самое лучшее - белый фон почти невидим, но он есть
oImagePainter.initFrom(this);
oImagePainter.setRenderHint(QPainter::Antialiasing, true);
oImagePainter.eraseRect(this->rect());
//test for state changes
QColor button_color;
if (this->isEnabled())
{
m_bHovered ? button_color = m_oHighlight : button_color = m_oColor;
if (m_bPressed) button_color = m_oPress;
}
else
{
button_color = QColor(50, 50, 50);
}
QRect button_rect = this->geometry();
//outline
oImagePainter.setPen(QPen(QBrush(Qt::black), 2.0));
QPainterPath outline;
outline.addRoundRect(0, 0, button_rect.width(), button_rect.height(), m_nRoundness, m_nRoundness);
oImagePainter.setOpacity(m_dOpacity);
oImagePainter.drawPath(outline);
//Linear Gradient
QLinearGradient oLinearGradient(0, 0, 0, button_rect.height());
oLinearGradient.setSpread(QGradient::ReflectSpread);
oLinearGradient.setColorAt(0.0, button_color);
oLinearGradient.setColorAt(0.4, m_oShadow);
oLinearGradient.setColorAt(0.6, m_oShadow);
oLinearGradient.setColorAt(1.0, button_color);
QBrush brush(oLinearGradient);
oImagePainter.setBrush(brush);
oImagePainter.setPen(QPen(QBrush(button_color), 2.0));
//main button
QPainterPath oImagePainter_path;
oImagePainter_path.addRoundRect(1, 1, button_rect.width() - 2, button_rect.height() - 2, m_nRoundness, m_nRoundness);
oImagePainter.setClipPath(oImagePainter_path);
oImagePainter.setOpacity(m_dOpacity);
oImagePainter.drawRoundRect(1, 1, button_rect.width() - 2, button_rect.height() - 2, m_nRoundness, m_nRoundness);
//glass highlight
oImagePainter.setBrush(QBrush(Qt::white));
oImagePainter.setPen(QPen(QBrush(Qt::white), 0.01));
oImagePainter.setOpacity(0.30);
oImagePainter.drawRect(1, 1, button_rect.width() - 2, (button_rect.height() / 2) - 2);
//text
QString sText = this->text();
if(!sText.isNull())
{
QFont font = this->font();
oImagePainter.setFont(font);
oImagePainter.setPen(Qt::white);
oImagePainter.setOpacity(1.0);
oImagePainter.drawText(0, 0, button_rect.width(), button_rect.height(), Qt::AlignCenter, sText);
}
oImagePainter.end();
QPainter oWidgetPainter(this);
//oWidgetPainter.setOpacity(m_dOpacity);//без разницы что включен, что нет
oWidgetPainter.drawImage(0, 0, oImage);
pEvent->accept();
}
Rocky, сделал попроще чем у тебя и всё работает (Проверял на виндовозе). Проверь
AeroButton2.zip ( 4.44 килобайт )
: 434
П.С. на окно добавил переключатель, чтобы рисовать напрямую или через QImage
Странно.. но действительно работает.. ))
дело было в fill(...)
=)
Rocky, отпишись, на Линухе использование QImage даёт лучшее сглаживание или нет.
Ну и если будешь продолжать использовать QImage, то лучше рисовать на QImage в отдельном методе, который вызывается в конструкторе и в методах установки свойств. А в обработчике события рисования только выводить уже готовый QImage (QPainter::drawImage()). Так будет быстрее отрисовка происходить
Да, насчет отрисовки завтра переделаю... Весь день буду оптимизацией заниматься... Хотя стоп... Litkevich Yuriy можно задам вопрос, который давно меня мучает... Вроде как он касается этого. Если в конструкторе класса формировать пусть тот же QImage, то как? В смысле если мы находимся внутри самого конструктора класса, то его объект еще не создан. И тем более не отображен на экране. Как тогда получить правильные размеры всех виджетов и пр? Я щас так делаю: просто в main-е после того, как вызвал exec(...) или show(...) главного окна, вызываю некий метод Initialize(...) который по сути далее вызывается иерархически по вссем потомкам главного виджета (окна).. Но как-то не очень нравится этот способ... Может можно как-то лучше?
Вобщем щас вот так в линуксе выглядит:
http://www.radikal.ru
Завтра на работе сделаю скрин как с этим же кодом в XP.
---------------------------------------
Вот так выглядит картинка в винде
http://www.radikal.ru
Все понятно.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)