Problem in using QGraphicsColorizeEffect for change color of a QFrame
-
Hi I want to change color of a QFrame with animation using
QPropertyAnimation
after some search I find out I can useQGraphicsColorizeEffect
withQPropertyAnimation
for this job. its kind of working, but my problem is its also change color of all widget that are inside of QFrame, I want it to just change the color of QFrame slowly from one color to another, and dont change color of any other widget inside of QFrame.
how can I get this working? thanks
btw, here is the code im using right nowQGraphicsColorizeEffect* eEffect = new QGraphicsColorizeEffect(ui.bg_app); ui.bg_app->setGraphicsEffect(eEffect); QPropertyAnimation* paAnimation = new QPropertyAnimation(eEffect, "color"); paAnimation->setStartValue(QColor(0, 14, 36, 255)); paAnimation->setEndValue(QColor(1, 33, 0, 255)); paAnimation->setDuration(2000); paAnimation->start();
-
Hi
QGraphicsColorizeEffect will affect any children so you need another solution if that is not wanted.Do you just want the background on the QFrame to fade colors or are you after the borders also change color?
If just background color I think you can pretty fast make a custom QFrame derived widget that does as you want.
-
Hi
Just in case.
What i mean is
from
#ifndef COLORFRAME_H #define COLORFRAME_H #include <QPainter> #include <QPropertyAnimation> #include <QStyleOptionFrame> #include <QWidget> class ColorFrame : public QFrame { Q_OBJECT QColor col; QPropertyAnimation *paAnimation; Q_PROPERTY(QColor color READ color WRITE setColor) public: explicit ColorFrame(QWidget *parent = nullptr) : QFrame(parent) { paAnimation = new QPropertyAnimation(this, "color"); paAnimation->setStartValue(QColor(0, 14, 36, 255)); paAnimation->setEndValue(QColor(255, 255, 255, 255)); paAnimation->setDuration(2000); paAnimation->start(); } QColor color() const { return col; } void setColor(const QColor &c) { col = c; update(); } void run() { paAnimation->start(); } protected: virtual void paintEvent(QPaintEvent *event) override { QPainter p(this); QStyleOptionFrame opt; initStyleOption(&opt); p.setBrush(col); style()->drawControl(QStyle::CE_ShapedFrame, &opt, &p, this); } virtual void mousePressEvent(QMouseEvent *event) override // this you dont need. its just to run it again :) { run(); } }; #endif // COLORFRAME_H
-
@saeid0034
Hi
Its hard to guess at with no code.Did you create an instance of ColorFrame and used that ?
-
@saeid0034
Hi
Nope, it was the same i did to test it.
Do note we call paAnimation->start(); when we create it. if only 2 secs duration, it can
be already over when MainWindow shows.Did you try to click the frame to have it run it again?
-
@mrjj thanks for help
so basically what I done is (For testing)
first create a header file in my project nameCOLORFRAME.h
and put your code in it
after that open up Qt designer and Promote my QFrame to this new created header file.
then compile my program, but nothing change at all...
maybe Im doing it wrong..? (btw Im using qt in vs2019) -
@saeid0034
Hi
Nope that sound pretty ok.
Try to change the duration to a longer and see.I think it jus thas run when you see you screen if still just 2 secs.
Also I change the colors a bit as the ones from your code were hard to see change.
So try change the time and colors and see. It should just work as it
sounds completely right how you did with the promotion. -
@mrjj its not working at all... and its also dont give me any error
here is my ui file that im using<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>testiiiiClass</class> <widget class="QMainWindow" name="testiiiiClass"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>600</width> <height>400</height> </rect> </property> <property name="windowTitle"> <string>testiiii</string> </property> <widget class="QWidget" name="centralWidget"> <layout class="QGridLayout" name="gridLayout_2"> <item row="0" column="0"> <widget class="ColorFrame" name="frame"> <property name="autoFillBackground"> <bool>false</bool> </property> <property name="styleSheet"> <string notr="true">background-color: rgb(3, 14, 36);</string> </property> <property name="frameShape"> <enum>QFrame::StyledPanel</enum> </property> <property name="frameShadow"> <enum>QFrame::Raised</enum> </property> </widget> </item> </layout> </widget> <widget class="QMenuBar" name="menuBar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>600</width> <height>21</height> </rect> </property> </widget> <widget class="QToolBar" name="mainToolBar"> <attribute name="toolBarArea"> <enum>TopToolBarArea</enum> </attribute> <attribute name="toolBarBreak"> <bool>false</bool> </attribute> </widget> <widget class="QStatusBar" name="statusBar"/> </widget> <layoutdefault spacing="6" margin="11"/> <customwidgets> <customwidget> <class>ColorFrame</class> <extends>QFrame</extends> <header>COLORFRAME.h</header> <container>1</container> </customwidget> </customwidgets> <resources> <include location="testiiii.qrc"/> </resources> <connections/> </ui>
I'm sure doing something wrong, but im not sure what...
-
Ahhh
Do you have a stylesheet on it ?
Let me check if that can work.Update:
Stylesheet is not the issue.You must set
As else the draw call does not erase the background :)
If you really dont want a border then you can fill the area yourself in its paintEvent.
Sorry. was not aware of this . a bit o.O
-
@mrjj oh thanks, now its fully working, but you right there is still a border that I need to change color of it too
i will be grateful if you can show a example of that too
thanks and sorry for asking too much
edit
its not exactly what i wanted, if i use this I can no longer use any stylesheet likeborder-radius
so I should look for another way -
another way that I find out (based of this link ) is to do it like this
class ColorFrame : public QFrame { Q_OBJECT QColor col; QPropertyAnimation *paAnimation; Q_PROPERTY(QColor color READ color WRITE setColor) public: explicit ColorFrame(QWidget *parent = nullptr) : QFrame(parent) { paAnimation = new QPropertyAnimation(this, "color"); paAnimation->setStartValue(QColor(0, 14, 36, 255)); paAnimation->setEndValue(QColor(255, 255, 255, 255)); paAnimation->setDuration(2000); paAnimation->start(); } QColor color() const { return col; } void setColor(const QColor& color) { setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(color.red()).arg(color.green()).arg(color.blue())); } void run() { paAnimation->start(); } protected: virtual void mousePressEvent(QMouseEvent *event) override // this you dont need. its just to run it again :) { run(); } };
its working and in this way I can also keep the stylesheet, but yet Im not sure if its the best way...