[Solved] QSplashScreen using a PNG with transparent areas
-
[quote author="Volker" date="1295008017"]Do you mind creating a wiki article in the "HowTo":http://developer.qt.nokia.com/wiki/Category:HowTo and/or "Code snippets":http://developer.qt.nokia.com/wiki/Category:snippets category? It would fit very well there![/quote]
Will do so!
-
Wiki: "splashscreen snippet":http://developer.qt.nokia.com/wiki/Custom_splashscreen_with_text
-
-
I have an image with an Alpha channel: am I correct in the assumption that the image (splash.png) you've used has no alpha channel and the mask (splashmask.png) is the (1 bit) alpha channel?
-
If the above assumptions are correct I still seem to have problems with the semi-transparent parts of my image. In my case there is a shadow that uses a multibit alpha channel that is not shown correctly.
-
For now I'm only able to show my splash screen properly using the following code:
@QPixmap aPixmap(":/splash.png");
QLabel* aWidget = new QLabel(0, Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
aWidget->setAttribute(Qt::WA_TranslucentBackground);
aWidget->setPixmap(aPixmap);
aWidget->show();
@ -
Is there maybe a way to have QSplashScreen show the images in the same way as QLabel does when using the Qt::WA_TranslucentBackground attribute ?
-
Is there maybe a way to to use QLabel as an alternative to QSplashScreen and add something similar to showMessage to the QLabel ?
-
-
[quote author="Dieter" date="1295332434"]
- Is there maybe a way to have QSplashScreen show the images in the same way as QLabel does when using the Qt::WA_TranslucentBackground attribute ?[/quote]
What do you mean? Did you read the BR I posted a link to?
[quote]
- Is there maybe a way to to use QLabel as an alternative to QSplashScreen and add something similar to showMessage to the QLabel ?
[/quote]
Use an ordinary QWidget with a QVBoxLayout holding two QLabels?
-
[quote author="peppe" date="1295366429"]What do you mean? Did you read the BR I posted a link to?[/quote]
Absolutely! I'm just trying to find a solution to my specific problem.[quote author="peppe" date="1295366429"]Use an ordinary QWidget with a QVBoxLayout holding two QLabels?[/quote]
I had some problems with the Qt::WA_TranslucentBackground attribute in QWidget but QFrame seems to work as expected and I will very soon post a solution that worked for me. -
It took me a while but I have finally found a very simple and perfect solution for my problem with semitransparent images using an alpha channel with more then 1 bit.
It all comes down to use a QFrame with the Qt::WA_TranslucentBackground attribute and emulate the functionality of QSplashScreen.
I have tried to mimic as much as possible the functionality and apperance of the original QSplashScreen class but left out some methods to keep this example simple.
- This is the new CSplashScreen class that must be used instead of QSplashScreen:
@
class CSplashScreen : public QFrame
{
public:
CSplashScreen(const QPixmap& pixmap);void clearMessage();
void showMessage(const QString& theMessage, int theAlignment = Qt::AlignLeft, const QColor& theColor = Qt::black);private:
virtual void paintEvent(QPaintEvent* pe);QPixmap itsPixmap;
QString itsMessage;
int itsAlignment;
QColor itsColor;
};
@- The methods in CSplashScreen:
@
CSplashScreen::CSplashScreen(const QPixmap& thePixmap)
: QFrame(0, Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint)
, itsPixmap(thePixmap)
{
setAttribute(Qt::WA_TranslucentBackground);
setFixedSize(itsPixmap.size());
};void CSplashScreen::clearMessage()
{
itsMessage.clear();
repaint();
}void CSplashScreen::showMessage(const QString& theMessage, int theAlignment/* = Qt::AlignLeft*/, const QColor& theColor/* = Qt::black*/)
{
itsMessage = theMessage;
itsAlignment = theAlignment;
itsColor = theColor;
repaint();
}void CSplashScreen::paintEvent(QPaintEvent* pe)
{
QRect aTextRect(rect());
aTextRect.setRect(aTextRect.x()+5, aTextRect.y()+5, aTextRect.width()-10, aTextRect.height()-10);QPainter aPainter(this);
aPainter.drawPixmap(rect(), itsPixmap);
aPainter.setPen(itsColor);
aPainter.drawText(aTextRect, itsAlignment, itsMessage);
}
@A simple function to the CSplashSCreen:
@
void
test_SplashScreen()
{
class SleeperThread : public QThread
{
public:
static void msleep(unsigned long msecs) {QThread::msleep(msecs);}
};QPixmap aSplashImage(":/splash.png");
CSplashScreen* aSplashScreen = new CSplashScreen(aSplashImage);
aSplashScreen->show();for (int i = 1; i <= 5; i++)
{
aSplashScreen->showMessage(QString("Processing %1...").arg(i), Qt::AlignTop | Qt::AlignLeft, Qt::white);
SleeperThread::msleep(1000);
}delete aSplashScreen;
}
@ -
Before marking this topic as solved, I have now also added a complete example "CSplashScreen":http://developer.qt.nokia.com/wiki/QSplashScreen_replacement_for_semitransparent_images" to the "Code snippets":http://developer.qt.nokia.com/wiki/Category:snippets WiKi.
Thank you all for all your help!
-
[quote author="Gerolf" date="1295535937"]Hi Dieter,
just one note, I would make the QPainter instance an object on the stack.
And second: are you sure you want to call the default implementation for the paint event? you do all painting yourselve, don't you?[/quote]I agree (and have already changed the code snippets)
-
Updated link to "CSplashScreen":http://qt-project.org/wiki/QSplashScreen-Replacement-for-Semitransparent-Images code snippets