使用 Qt 将平面图像转换为带有 3D 高光的漂亮圆形图像,就像 iPhone 一样

发布于 2024-08-02 22:41:15 字数 111 浏览 4 评论 0原文

在 iPhone 上,您为应用程序图标提供 45x45 平面图像,SDK 会自动为您舍入并突出显示它,从而赋予其新的 3D 效果。有谁有关于如何使用 Qt4 API 进行模拟的示例代码或建议吗?谢谢,--DD

On the iPhone, you give it your 45x45 flat image for the app icon, and the SDK rounds and highlights it for you automatically, giving it a new 3D effect. Does anyone have sample code or recommendations on how to emulate this using Qt4 APIs? Thanks, --DD

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风铃鹿 2024-08-09 22:41:15

如果您想要 iPhone 应用程序图标的完整效果:圆角矩形、赋予其 3D 外观的微妙渐变和光泽,我不确定样式表是否可以满足您所要求的所有要求。但也许可以,如果你可以将两个图像叠加在一起。一种可能是具有透明度的圆形 3D 蒙版图像,然后您只需将 45X45 图像放在其后面即可。但是,我现在不知道 qstylesheets 的可扩展性如何。

然而,另一种选择是使用 QPainter。它绝对可以满足您的所有要求。基本上你想要做的是覆盖你的小部件、QPushButton、QLabel...等的paintEvent()。并使用源图像自己绘制。以下是我在自定义绘制 QPushButton 时所做的 wiki 条目的链接,以使其具有 Windows Aero 外观,这与 iphone 应用程序图标没有什么不同: http://wiki.qtcentre.org/index.php?title=AeroButton

这里是类中的paintEvent(),给你一个起点。一旦你进入它,使用助手,它就非常简单:

 void AeroButton::paintEvent(QPaintEvent * pe)
 {
     Q_UNUSED(pe);

     QPainter painter(this);  
     painter.setRenderHint(QPainter::Antialiasing);

     //test for state changes
     QColor button_color;
     if(this->isEnabled())
     {
         m_hovered ? button_color = m_highlight : button_color = m_color;

         if(m_pressed)
         {
              button_color = m_highlight.darker(250);
         }
     }
     else
     {
         button_color = QColor(50, 50, 50);
     }

     QRect button_rect = this->geometry();

     //outline
     painter.setPen(QPen(QBrush(Qt::black), 2.0));
     QPainterPath outline;
     outline.addRoundedRect(0, 0, button_rect.width(), button_rect.height(), m_roundness, m_roundness);
     painter.setOpacity(m_opacity);
     painter.drawPath(outline);

     //gradient
     QLinearGradient gradient(0, 0, 0, button_rect.height());
     gradient.setSpread(QGradient::ReflectSpread);
     gradient.setColorAt(0.0, button_color);
     gradient.setColorAt(0.4, m_shadow);
     gradient.setColorAt(0.6, m_shadow);
     gradient.setColorAt(1.0, button_color);

     QBrush brush(gradient);
     painter.setBrush(brush); 
     painter.setPen(QPen(QBrush(button_color), 2.0));

     //main button
     QPainterPath painter_path;
     painter_path.addRoundedRect(1, 1, button_rect.width() - 2, button_rect.height() - 2, m_roundness, m_roundness);
     painter.setClipPath(painter_path);

     painter.setOpacity(m_opacity);
     painter.drawRoundedRect(1, 1, button_rect.width() - 2, button_rect.height() - 2, m_roundness, m_roundness);

     //glass highlight
     painter.setBrush(QBrush(Qt::white));
     painter.setPen(QPen(QBrush(Qt::white), 0.01));
     painter.setOpacity(0.30);
     painter.drawRect(1, 1, button_rect.width() - 2, (button_rect.height() / 2) - 2);

     //text
     QString text = this->text();
     if(!text.isNull())
     {
         QFont font = this->font();
         painter.setFont(font);
         painter.setPen(Qt::white);
         painter.setOpacity(1.0);
         painter.drawText(0, 0, button_rect.width(), button_rect.height(), Qt::AlignCenter, text);
     }

      //icon
      QIcon icon = this->icon();
      if(!icon.isNull())
      {
         QSize icon_size = this->iconSize();
         QRect icon_position = this->calculateIconPosition(button_rect, icon_size);
         painter.setOpacity(1.0);
         painter.drawPixmap(icon_position, QPixmap(icon.pixmap(icon_size)));
      }
 }

I'm not sure a style sheet could do all you are asking for, if you want the full effect of the iphone app icons: the rounded rectangle, the subtle gradient to give it the 3D look, and the shine. But perhaps it could, if you could overlay two images on top of one another. One could be the rounded 3D mask image with transparency, then you just put your 45X45 image behind it. But then, I don't know how extensible qstylesheets are at this point.

However, another alternative is to use QPainter. It can definitely do all you require. Basically what you would want to do is override the paintEvent() of your widget, QPushButton, QLabel...etc. and draw it yourself using the source image. Here is a link to a wiki entry I did on custom-painting a QPushButton to give it an Windows Aero look, which is not dissimilar to the iphone app icon: http://wiki.qtcentre.org/index.php?title=AeroButton

And here is the paintEvent() from the class, to give you a starting point. Once you get into it, using the Assistant, it's pretty straightforward:

 void AeroButton::paintEvent(QPaintEvent * pe)
 {
     Q_UNUSED(pe);

     QPainter painter(this);  
     painter.setRenderHint(QPainter::Antialiasing);

     //test for state changes
     QColor button_color;
     if(this->isEnabled())
     {
         m_hovered ? button_color = m_highlight : button_color = m_color;

         if(m_pressed)
         {
              button_color = m_highlight.darker(250);
         }
     }
     else
     {
         button_color = QColor(50, 50, 50);
     }

     QRect button_rect = this->geometry();

     //outline
     painter.setPen(QPen(QBrush(Qt::black), 2.0));
     QPainterPath outline;
     outline.addRoundedRect(0, 0, button_rect.width(), button_rect.height(), m_roundness, m_roundness);
     painter.setOpacity(m_opacity);
     painter.drawPath(outline);

     //gradient
     QLinearGradient gradient(0, 0, 0, button_rect.height());
     gradient.setSpread(QGradient::ReflectSpread);
     gradient.setColorAt(0.0, button_color);
     gradient.setColorAt(0.4, m_shadow);
     gradient.setColorAt(0.6, m_shadow);
     gradient.setColorAt(1.0, button_color);

     QBrush brush(gradient);
     painter.setBrush(brush); 
     painter.setPen(QPen(QBrush(button_color), 2.0));

     //main button
     QPainterPath painter_path;
     painter_path.addRoundedRect(1, 1, button_rect.width() - 2, button_rect.height() - 2, m_roundness, m_roundness);
     painter.setClipPath(painter_path);

     painter.setOpacity(m_opacity);
     painter.drawRoundedRect(1, 1, button_rect.width() - 2, button_rect.height() - 2, m_roundness, m_roundness);

     //glass highlight
     painter.setBrush(QBrush(Qt::white));
     painter.setPen(QPen(QBrush(Qt::white), 0.01));
     painter.setOpacity(0.30);
     painter.drawRect(1, 1, button_rect.width() - 2, (button_rect.height() / 2) - 2);

     //text
     QString text = this->text();
     if(!text.isNull())
     {
         QFont font = this->font();
         painter.setFont(font);
         painter.setPen(Qt::white);
         painter.setOpacity(1.0);
         painter.drawText(0, 0, button_rect.width(), button_rect.height(), Qt::AlignCenter, text);
     }

      //icon
      QIcon icon = this->icon();
      if(!icon.isNull())
      {
         QSize icon_size = this->iconSize();
         QRect icon_position = this->calculateIconPosition(button_rect, icon_size);
         painter.setOpacity(1.0);
         painter.drawPixmap(icon_position, QPixmap(icon.pixmap(icon_size)));
      }
 }
时常饿 2024-08-09 22:41:15

(这是一个建议,因为我还没有真正尝试过)

样式表即:

QPushButton {
    background: qlineargradient( /*specify pattern here, with colors with alpha channel (0, 0, 0, 150) for example */ ); 
    image: url(:/reference/to/img/in_q_resourceFile);
}

我认为这将是最简单的解决方案,因为它会给你一个可点击的qpushbutton。

参考助手如何写样式表...

(This is a suggestion because I have not actually tried it)

Stylesheet i.e :

QPushButton {
    background: qlineargradient( /*specify pattern here, with colors with alpha channel (0, 0, 0, 150) for example */ ); 
    image: url(:/reference/to/img/in_q_resourceFile);
}

I think this would be the easiest solution, as it would give you a clickable qpushbutton.

Refer to the assistant on how to write stylesheets...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文