2

I am making a desktop carousel app. There I need to show image widgets, which might contain other sub-widgets as well. For that I am using a QFrame with the required image as background. Here is the image I am trying to use: image link. What I want is that only the image shows up, no background image or anything shows up as well, so to the user it looks like just the image. Here is my code:

setGeometry(QRect(100, 20, 325,400));
setFrameStyle(QFrame::StyledPanel);
setStyleSheet("QFrame#ImageFrame { background-color: transparent; background: url(:icon/ipad-skin); }");
setAutoFillBackground(false);

However, I am getting this as a result:

enter image description here

I tried this as well (obtained from here) (and removing the stylesheet):

void MyWidget::paintEvent(QPaintEvent *p)
{
    QPainter* pPainter = new QPainter(this);
    pPainter->drawPixmap(rect(), QPixmap(":icon/newskin.png"));
    delete pPainter;
    QWidget::paintEvent(p);
}

Nothing different, the exact same result. The greyness of the background still shows.

How do I make the grey background of the QFrame go and display only the image (the dimensions I am setting are the same as the image)?

P.S I am aware that similar questions hve been answered here: QWidget transparent background (but not the children), and here: Frameless and transparent window qt5 but these doesn't solve my problem. The last solution makes my QFrame look like this:

enter image description here

The QFrame now comes with a title bar which is anything but what I wanted in the first place.

Edit - This solution works, but in my use-case, I need to display an image that is rendered via GL inside the QFrame (specifically, in the viewport within the iPad image we can see here). In Windows, setting the Qt::WA_TranslucentBackground property makes that GL-rendered image invisible. It works fine in Mac, though. So I am looking for a solution which will work in Windows as well.

Community
  • 1
  • 1
SexyBeast
  • 7,913
  • 28
  • 108
  • 196

2 Answers2

6

This code works for me (tested under MacOS/X 10.10.3, using Qt 5.5.0-beta; I'd expect it to work under any Qt version 4.5.0 or higher though):

main.h:

#ifndef main_h
#define main_h

#include <QFrame>
#include <QPixmap>

class MyFrame : public QFrame
{
public:
   MyFrame(QWidget * parent);

   virtual void paintEvent(QPaintEvent * e);

private:
   QPixmap _pixmap;
};

#endif

main.cpp:

#include <QApplication>
#include <QPainter>
#include "main.h"

MyFrame :: MyFrame(QWidget * parent) : QFrame(parent, Qt::Window|Qt::FramelessWindowHint)
{
   setAttribute(Qt::WA_TranslucentBackground);

   _pixmap.load("/Users/jaf/iPad_Vector.png");
   resize(_pixmap.size());
}

void MyFrame :: paintEvent(QPaintEvent * /*e*/)
{
   QPainter p(this);
   p.drawPixmap(0,0,width(),height(), _pixmap);
}

int main(int argc, char ** argv)
{
   QApplication app(argc, argv);

   MyFrame f(NULL);
   f.show();

   return app.exec();
}

Screenshot (showing the app's window in front of my desktop background):

screenshot

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
  • Note: If you need to change to a different pixmap, you can either call _pixmap.load("some_other_image.png") again, and then call update(), or if you want to be more efficient about it, you can have multiple QPixmap member variables loaded at startup and choose the appropriate one to call drawPixmap() with, inside paintEvent(). (Again, call update() to force paintEvent() to be called again) – Jeremy Friesner Jun 23 '15 at 18:45
  • Thanks! Worked like a charm! – SexyBeast Jun 24 '15 at 18:51
  • By the way, the images look a bit little rough at the corners. Very minute, you have to peer into the screen to spot it, but it's there. The actual image is smooth though. Any way to fix that? – SexyBeast Jun 29 '15 at 05:49
  • 1
    You could try calling setRenderHint() on your QPainter with various values to see if it makes any difference; I don't know that it will though. – Jeremy Friesner Jun 29 '15 at 21:44
  • You are an angel! `QPainter::SmoothPixmapTransform` did the trick! – SexyBeast Jun 30 '15 at 01:35
  • Hey, sorry to bump this up, but I am having some problem with this method. Not this method per se, it works fine as expected, but in the device viewport we are showing some image that has been rendered via GL. Now calling `setAttribute(Qt::WA_TranslucentBackground);` on the frame renders the image invisible in Windows, and is a known GL issue. Is there any way I can achieve this without using that attribute? – SexyBeast Dec 17 '15 at 20:48
  • I doubt it... unless there is a Qt::WA_TranlucentBackgroundThatDoesntBreakOpenGL flag hidden in the Qt headers somewhere... ;) your best bet is to ask the Qt people to fix their bug. – Jeremy Friesner Dec 18 '15 at 01:29
1

Can you try this light modification to your code ?

In case it doesn't work can you publish your compilable code on a public repository ? This would help reproduce in your exact context.

void MyWidget::paintEvent(QPaintEvent *p)
{
    QPainter* pPainter = new QPainter(this);
    pPainter->setBackgroundMode(Qt::TransparentMode);
    pPainter->drawPixmap(rect(), QPixmap(":icon/newskin.png"));
    delete pPainter;
    QWidget::paintEvent(p);
}
fjardon
  • 7,921
  • 22
  • 31