View Full Version : Set opacity in Linux
Momergil
17th June 2014, 13:21
Hello!
I want to add some "fading" effect (I guess that's the name) in a pop-up widget in one of my applications for Linux when the widget is both shown and hidden. I'ld guess that the normal way of doing this is to add a QPropertyAnimation that would change the window's opacity from 0 to 255 in a period of time (lets say 500 ms).
Now the problem is that in the Linux I'm using window opacity is not available; so I both can't change the window opacity with QProperyAnimation, nor with setWindowOpacity(qreal).
The question: how do I do this, then? I tried with stylesheet (connecting a slot to the QProperyAnimation and changing the window's background-color alpha channel from 0 to 255) but it doesn't seem to be interesting setting a new stylesheet so quickly (calling a set QString method frequently), nor is it elegant.
I wonder if there is another way of doing this for this circumstance that is not by stylesheet?
I'm glad for any help,
Momergil
Note: using Qt 4.8 for ARM
anda_skoa
17th June 2014, 15:05
Now the problem is that in the Linux I'm using window opacity is not available
Yes, it is.
Just tried with
#include <QApplication>
#include <QLabel>
#include <QPropertyAnimation>
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
QLabel label("Hello World");
label.show();
QPropertyAnimation fade(&label, "windowOpacity");
fade.setStartValue(1.0);
fade.setEndValue(1.0);
fade.setKeyValueAt(0.5, 0.0);
fade.setDuration(5000);
fade.start();
return app.exec();
}
A window with the label in it appears, fades out and fades in again.
Cheers,
_
Momergil
17th June 2014, 16:13
Hello anda_skoa!
First, thanks for the reply.
Second, I was quite interested when you provided a direct use of QPropertyAnimation as a solution to my problem, since (as I mentioned above) I've tried that solution before without success. I decided to give a try, nonetheless, and for my surprise your code actually worked.
I began to make comparisons between your QPropertyAnimation implementation and mine (having done the proper adaptations) and despite various checkings and debugs, I simply couldn't make my code work; the fade effect simply don't happen.
So the code I'm using is below. As you may see, it's supposed to be a replacement of QMessageBox that is activated once the user clicks in a place, when the show1() method is called. It should than start the fade effect on poBaseWidget, and once the user clicks on it, a new closing fade should occur. Could you please tell me why it's not working?
Thanks,
Momergil
class MessageFrame : public QFrame
{
Q_OBJECT
Q_PROPERTY(QString currentText READ currentText WRITE setCurrentText)
Q_ENUMS(Icon)
Q_ENUMS(TextType)
public:
enum Icon { Question, Information, Warning, Critical };
enum TextType { ScreenDescription, GeneralText };
MessageFrame(QWidget* parent = 0) :
QFrame(parent),
poBaseWidget(new QFrame(this))
{
setObjectName("MessageFrame");
setGeometry(0,20,800,460);
//
poBaseWidget->setGeometry(120,0,560,100);
poBaseWidget->setStyleSheet("* { background-color: rgb(192,192,192);"
"background-origin: content;"
"border: 2px rgb(128,128,127);"
"border-radius: 10px; }");
//
iconLabel = new QLabel(poBaseWidget);
iconLabel->resize(32,32);
setIcon(Information);
//
textLabel = new QLabel(poBaseWidget);
textLabel->setWordWrap(true);
textLabel->setMaximumSize(textLabel->parentWidget()->width() - iconLabel->width() - 20, textLabel->parentWidget()->height() - 10);
textLabel->resize(textLabel->maximumSize());
//
startFadeAnimation = new QPropertyAnimation(poBaseWidget, "windowOpacity",this);
startFadeAnimation->setStartValue(0.0);
startFadeAnimation->setEndValue(1.0);
startFadeAnimation->setDuration(5000);
stopFadeAnimation = new QPropertyAnimation(poBaseWidget, "windowOpacity",this);
stopFadeAnimation->setStartValue(1.0);
stopFadeAnimation->setEndValue(0.0);
stopFadeAnimation->setDuration(5000);
connect(stopFadeAnimation,SIGNAL(finished()),this, SLOT(close()));
//
poBaseWidget->installEventFilter(this);
hide(); //hide();
}
virtual ~MessageFrame()
{
poBaseWidget->removeEventFilter(this);
}
inline QString currentText() const;
void setCurrentText(const QString& text);
void setIcon(const Icon icon);
static void information(const QString& text);
static void warning(const QString& text);
static void critical(const QString& text);
private:
QLabel* textLabel,
* iconLabel;
QPropertyAnimation* startFadeAnimation,
* stopFadeAnimation;
QString screenText;
QFrame* poBaseWidget;
protected:
bool eventFilter(QObject *obj, QEvent *ev)
{
if (obj == poBaseWidget && ev->type() == QEvent::MouseButtonRelease)
{
stopFadeAnimation->start();
return true;
}
else
return QFrame::eventFilter(obj,ev);
}
public slots:
void show1(const TextType type = GeneralText)
{
switch (type)
{
case GeneralText: //last set text
break;
case ScreenDescription:
// setCurrentText(screenText);
break;
}
show();
startFadeAnimation->start();
}
inline void setScreenText(const QString& text) { screenText = text; }
/////////////////////////////////////////////////////
/// SINGLETON STUFF - DON'T TOUCH
public:
static void start(QWidget* parent = 0);
static void MessageFrameDestroy();
inline static MessageFrame& instance();
private:
static MessageFrame* poInstance;
};
wysota
18th June 2014, 07:42
You are animating windowOpacity of poBaseWidget instead of your MessageFrame instance. Only top-level windows can have their windowOpacity manipulated.
Momergil
18th June 2014, 12:21
You are animating windowOpacity of poBaseWidget instead of your MessageFrame instance. Only top-level windows can have their windowOpacity manipulated.
Oh, I remember reading that in the manual; I didn't noticed I was doing that in my code. Anyway, why is that so? And, well, if the method show by anda_skoa is valid only for top-level windows, I'll restate my first question to: is there a way to create such a "fade" effect that is not by stylesheet and that is valid for any widget I want to apply the effect regardless of being a top level widget or not?
anda_skoa
18th June 2014, 12:49
So you want the content of the window to fade, not the window itself?
Maybe usingQGraphicsOpacityEffect on the widget which you want to fade.
Cheers,
_
Momergil
18th June 2014, 14:02
So you want the content of the window to fade, not the window itself?
Exactly, and your suggestion worked perfectly. Thanks!
Momergil
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.