views:

706

answers:

2

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

A: 

(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...

Karol Wilk
+5  A: 

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)));
      }
 }
JimDaniel