January 12, 2011

Dieter Dieter
Lab Rat
94 posts

[Solved] QSplashScreen using a PNG with transparent areas

Page  
1

Should the QSplashScreen class support the use of a PNG with transparent areas?

My code looks as follows:

  1. QPixmap aPixmap(":/splash.png");
  2. aSplashScreen = new QSplashScreen(aPixmap);
  3. aSplashScreen->setMask(aPixmap.mask());
  4. aSplashScreen->show();

Instead of seeing the background in the transparent areas I just seem them white.

Thank you in advance!

26 replies

January 12, 2011

Gerolf Gerolf
Robot Herder
3235 posts

If the png is transparent, you will see the widget background (which might be white :-( ).
You could try making the QSplashScreen object with transparent background [developer.qt.nokia.com]

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

January 12, 2011

ucomesdag ucomesdag
Lab Rat
243 posts

Did you set the correct window flags?

  1. setWindowFlags(Qt::WindowStaysOnTopHint | Qt::SplashScreen)

 Signature 

Write “Qt”, not “QT” (QuickTime).

January 13, 2011

Dieter Dieter
Lab Rat
94 posts
ucomesdag wrote:
Did you set the correct window flags? @setWindowFlags(Qt::WindowStaysOnTopHint | Qt::SplashScreen)@

I double checked the QSplashScreen documentation (clearly test it as well) and it seems to me as if Qt::WindowStaysOnTopHint hint would be optional and Qt::SplashScreen redundant.

January 13, 2011

Dieter Dieter
Lab Rat
94 posts
Gerolf wrote:
If the png is transparent, you will see the widget background (which might be white :-( ). You could try making the QSplashScreen object with transparent background [developer.qt.nokia.com]

I’ve tried to understand how the information in your link relates to QSplashScreen but I’m not sure on what to do. Would you be so kind and explain in more detail on how you think I can make the QSplashScreen object with “transparent background”. A small example would be most appreciated.

January 13, 2011

Dieter Dieter
Lab Rat
94 posts

I have in the meantime done some more testing and it is interesting to see what the different in using the

  1. aSplashScreen->setMask(aPixmap.mask());
line makes:

without using setMask:

when using setMask:

January 13, 2011

Gerolf Gerolf
Robot Herder
3235 posts

That has a similar effect, but a mask does not make alpha, it makes transparent or not.

A top level widget (QSplashScreen is a widget) can be transparent. Sorry, I didn’t read the complete article before. Currently I can’t test it, but you could play with the following things:

  • setWindowOpacity(xxx);
  • setAttribute(Qt::WA_NoBackground);
  • setAttribute(Qt::WA_NoSystemBackground);
  • setAttribute(Qt::WA_TranslucentBackground);
 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

January 13, 2011

Dieter Dieter
Lab Rat
94 posts

Gerolf wrote:
That has a similar effect, but a mask does not make alpha, it makes transparent or not.

A top level widget (QSplashScreen is a widget) can be transparent. Sorry, I didn’t read the complete article before. Currently I can’t test it, but you could play with the following things:

  • setWindowOpacity(xxx);
  • setAttribute(Qt::WA_NoBackground);
  • setAttribute(Qt::WA_NoSystemBackground);

Thank you for the additional information but unfortunately it seem not to solve my problem:

setWindowOpacity(.75);
Makes the complete widget 75% translucent but does not affect the area using the alpha channel.

setAttribute(Qt::WA_NoBackground);
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_TranslucentBackground);
All tree attributes just make the background of the window black and the area involved depends on the use of setMask.

January 13, 2011

Mohsen Mohsen
Lab Rat
748 posts

what OS you’re using?

 Signature 

www.madagon.com

January 13, 2011

Dieter Dieter
Lab Rat
94 posts

Currently testing on OSX and Windows.

January 13, 2011

peppe peppe
Ant Farmer
1026 posts

Use a QLabel instead.

http://bugreports.qt.nokia.com/browse/QTBUG-12820

 Signature 

Software Engineer
KDAB (UK) Ltd., a KDAB Group company

January 14, 2011

Mohsen Mohsen
Lab Rat
748 posts

if the form transparency is the problem, there wont be difference in using objects.

peppe wrote:
Use a QLabel instead.

http://bugreports.qt.nokia.com/browse/QTBUG-12820

 Signature 

www.madagon.com

January 14, 2011

Dieter Dieter
Lab Rat
94 posts
peppe wrote:
Use a QLabel instead. http://bugreports.qt.nokia.com/browse/QTBUG-12820

Thank you for the hint! I really seem to have hit bug 12820.

The following code seems to work as expected:

  1. QPixmap aPixmap(":/splash.png");
  2. QLabel* aWidget = new QLabel(0, Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
  3. aWidget->setAttribute(Qt::WA_TranslucentBackground);
  4. aWidget->setPixmap(aPixmap);
  5. aWidget->show();

I’m actually surprised to hit a bug in a rather prominent class like QSplashScreen. As there is no information on when this bug will be fixed it might make sense to vote for it.

Does someone eventually have a workaround to get this working in a QSplashScreen?

January 14, 2011

ucomesdag ucomesdag
Lab Rat
243 posts

I got it working by subclassing QSplashScreen, setting QSplashScreen::setPixmap(QPixmap splash); and setting the mask to the subclass, setMask(QPixmap mask); .

Splash image with a text display:

screencap

main:

  1. QPixmap splashImage(":images/splash.png");
  2. QPixmap splashMask(":images/splashmask.png");
  3.  
  4. customSplashScreen *splash = new customSplashScreen(splashImage);
  5. splash->setMessageRect(QRect::QRect(7, 253, 415, 14), Qt::AlignCenter); // Setting the message position.
  6.  
  7. QFont splashFont;
  8. splashFont.setFamily("Arial");
  9. splashFont.setBold(true);
  10. splashFont.setPixelSize(9);
  11. splashFont.setStretch(125);
  12.  
  13. splash->setFont(splashFont);
  14. splash->setMask(splashMask);
  15. splash->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::SplashScreen);
  16. splash->show();
  17.  
  18. /* To intercept mousclick to hide splash screen. Since the
  19. splash screen is typically displayed before the event loop
  20. has started running, it is necessary to periodically call. */
  21. app.processEvents();
  22.  
  23. splash->showStatusMessage(QObject::tr("Initializing..."));

customSplashScreen.h:

  1. #ifndef CUSTOMSPLASHSCREEN_H
  2. #define CUSTOMSPLASHSCREEN_H
  3.  
  4. #include <QSplashScreen>
  5. #include <QPainter>
  6.  
  7. class customSplashScreen
  8.  :public QSplashScreen
  9. {
  10.  
  11. public:
  12.  customSplashScreen(const QPixmap& pixmap);
  13.  ~customSplashScreen();
  14.  virtual void drawContents(QPainter *painter);
  15.  void showStatusMessage(const QString &message, const QColor &color = Qt::black);
  16.  void setMessageRect(QRect rect, int alignment = Qt::AlignLeft);
  17.  
  18. private:
  19.  QString message;
  20.  int alignement;
  21.  QColor color;
  22.  QRect rect;
  23. };
  24.  
  25. #endif // CUSTOMSPLASHSCREEN_H

customSplashScreen.cpp:

  1. #include "customSplashScreen.h"
  2.  
  3. customSplashScreen::customSplashScreen(const QPixmap& pixmap)
  4. {
  5.  QSplashScreen::setPixmap(pixmap);
  6. };
  7.  
  8. customSplashScreen::~customSplashScreen()
  9. {
  10. };
  11.  
  12. void customSplashScreen::drawContents(QPainter *painter)
  13. {
  14.  QPixmap textPix = QSplashScreen::pixmap();
  15.  painter->setPen(this->color);
  16.  painter->drawText(this->rect, this->alignement, this->message);
  17. };
  18.  
  19. void customSplashScreen::showStatusMessage(const QString &message, const QColor &color)
  20. {
  21.  this->message = message;
  22.  this->color = color;
  23.  this->showMessage(this->message, this->alignement, this->color);
  24. };
  25.  
  26. void customSplashScreen::setMessageRect(QRect rect, int alignement)
  27. {
  28.  this->rect = rect;
  29.  this->alignement = alignement;
  30. };

 Signature 

Write “Qt”, not “QT” (QuickTime).

January 14, 2011

Dieter Dieter
Lab Rat
94 posts

ucomesdag wrote:
I got it working by subclassing QSplashScreen, setting QSplashScreen::setPixmap(QPixmap splash); and setting the mask to the subclass, setMask(QPixmap mask); .

Splash image with a text display:


Thank you very much!
Your approach look very promising.
How exactly did you setup (alpha channel) the two images you are using?

January 14, 2011

ucomesdag ucomesdag
Lab Rat
243 posts

The splash image:
splash

and the mask:
mask

 Signature 

Write “Qt”, not “QT” (QuickTime).

Page  
1

  ‹‹ Qss and bottom-border      QGraphicsScene drag and drop ››

You must log in to post a reply. Not a member yet? Register here!