Set Gif as Background of QFrame.
-
Hallo,
is there a possibility to set a gif as background of a QFrame?
I already tried QMovie but QFrame doesnt have ->setIcon or ->setMovie
I cant use QLable, because i have to display a QLable in front of the GIF and i cant put subordinate a QLable in a QLable.Is there a other way?
Thanks
-
@AlexKrammer One possible solution is to use a QGraphicsEffect:
#include <QApplication> #include <QFrame> #include <QGraphicsEffect> #include <QGridLayout> #include <QLabel> #include <QMainWindow> #include <QMovie> #include <QPainter> class GifEffect: public QGraphicsEffect{ public: using QGraphicsEffect::QGraphicsEffect; QMovie* movie() const{ return mMovie.data(); } void setMovie(QMovie *movie){ mMovie = movie; if(!mMovie){ update(); return; } connect(mMovie.data(), &QMovie::updated, this, &GifEffect::update); connect(mMovie.data(), &QMovie::resized, this, &GifEffect::update); update(); } protected: void draw(QPainter *painter){ if(!mMovie){ drawSource(painter); return; } QPoint offset; Qt::CoordinateSystem system = sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates; QPixmap pixmap = sourcePixmap(system, &offset, QGraphicsEffect::NoPad); if (pixmap.isNull()) return; painter->save(); if (system == Qt::DeviceCoordinates) painter->setWorldTransform(QTransform()); if(!mMovie->currentPixmap().isNull()) painter->drawPixmap(offset, mMovie->currentPixmap().scaled(boundingRect().size().toSize())); painter->drawPixmap(offset, pixmap); painter->restore(); } private: QPointer<QMovie> mMovie; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow w; QFrame *frame = new QFrame; QGridLayout *lay = new QGridLayout(frame); lay->addWidget(new QLabel("Foo"), 1, 1); lay->setRowStretch(0, 1); lay->setRowStretch(2, 1); lay->setColumnStretch(0, 1); lay->setColumnStretch(2, 1); GifEffect *effect = new GifEffect(frame); QMovie *movie = new QMovie(frame); movie->setFileName("/path/of/filename.gif"); movie->start(); effect->setMovie(movie); frame->setGraphicsEffect(effect); w.setCentralWidget(frame); w.resize(640, 480); w.show(); return a.exec(); };
-
Hi
well subclass Qlabel paintEvent.
Call inherited paintEvent
QLabel::paintEvent(event);and the create a painter
and draw the overlay text. -
Honestly i dont know how to do it? I've never heard anything about it?
-
Right now i have this constellation.
And is there also the possibility to make the text like mine again, with black border and white background and also the gif as background?
-
Hi
Well something like#include <QLabel> #include <QPainter> class OverLayLabel : public QLabel { Q_OBJECT public: explicit OverLayLabel(QLabel *parent = nullptr) : QLabel(parent) { } protected: virtual void paintEvent(QPaintEvent *event) override { QLabel::paintEvent(event); QPainter p(this); p.drawText(10, 10, "im over"); } };
You need to assign the Qmovie as normal and use an instance of this class instead of the normal
QLabel. You can also draw with painter, both such round borders and use big font for the number
or anything else you like. -
A QLabel can contain either a text or an image. Not both at same time. If you want to have an image as a background to a text, you will need to either use a QTextView and setup your text and background image as rich text, overlay two QLabel instances on top of each other with the image being the bottom one, or implement your own custom QWidget. The latter can be done in a variety of ways, including subclassing QLabel to in paintEvent first render the background image (see QPainter's documentation on how to draw a QImage or better, a QPixmap) and then call the base implementation of paintEvent to render the text.
https://stackoverflow.com/questions/53913695/set-image-as-background-and-text-on-top-of-it-in-qlabelAnother way to do it: create two exactly same qlabels for text and icon. Then overlay them with text label on top which has transparent background and a border( created with style sheet)
-
First i try to call the QMovie in QLable.
That works, but not perfect. Its not centered in the QLabel...
But i can the the animation.Well,
when i try your idea, i get the error message "paintEvent is a protected member of QLabel, too few arguments to function callhow does this work? What is my mistake?
-
Isnt there the option to set the background gif by stylesheet?
-
@AlexKrammer
GIF is a movie. There is no way you can use it as background. -
@AlexKrammer One possible solution is to use a QGraphicsEffect:
#include <QApplication> #include <QFrame> #include <QGraphicsEffect> #include <QGridLayout> #include <QLabel> #include <QMainWindow> #include <QMovie> #include <QPainter> class GifEffect: public QGraphicsEffect{ public: using QGraphicsEffect::QGraphicsEffect; QMovie* movie() const{ return mMovie.data(); } void setMovie(QMovie *movie){ mMovie = movie; if(!mMovie){ update(); return; } connect(mMovie.data(), &QMovie::updated, this, &GifEffect::update); connect(mMovie.data(), &QMovie::resized, this, &GifEffect::update); update(); } protected: void draw(QPainter *painter){ if(!mMovie){ drawSource(painter); return; } QPoint offset; Qt::CoordinateSystem system = sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates; QPixmap pixmap = sourcePixmap(system, &offset, QGraphicsEffect::NoPad); if (pixmap.isNull()) return; painter->save(); if (system == Qt::DeviceCoordinates) painter->setWorldTransform(QTransform()); if(!mMovie->currentPixmap().isNull()) painter->drawPixmap(offset, mMovie->currentPixmap().scaled(boundingRect().size().toSize())); painter->drawPixmap(offset, pixmap); painter->restore(); } private: QPointer<QMovie> mMovie; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow w; QFrame *frame = new QFrame; QGridLayout *lay = new QGridLayout(frame); lay->addWidget(new QLabel("Foo"), 1, 1); lay->setRowStretch(0, 1); lay->setRowStretch(2, 1); lay->setColumnStretch(0, 1); lay->setColumnStretch(2, 1); GifEffect *effect = new GifEffect(frame); QMovie *movie = new QMovie(frame); movie->setFileName("/path/of/filename.gif"); movie->start(); effect->setMovie(movie); frame->setGraphicsEffect(effect); w.setCentralWidget(frame); w.resize(640, 480); w.show(); return a.exec(); };
-
@AlexKrammer said in Set Gif as Background of QFrame.:
That works, but not perfect. Its not centered in the QLabel...
Set the alignment of the QLabel to center. Its left or default.
- when i try your idea, i get the error message "paintEvent is a protected member of QLabel, too few arguments to function call
You have to show what you have of code as it compiles fine here.
-
Thank you,
in my testprogram it works.
I created a new Class called GifEffect, as you did.
Then in the mainwindow.h i added the class and i created:#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_btn_ON_clicked() { GifEffect *effect = new GifEffect(); QMovie *movie = new QMovie("C:/Users/akrammer/Documents/untitled/giphy.gif"); movie->setFileName(":/Documents/untitled/giphy.gif"); movie->start(); effect->setMovie(movie); ui->frm_BG->setGraphicsEffect(effect); } void MainWindow::on_btn_OFF_clicked() { ui->frm_BG->setGraphicsEffect(Q_NULLPTR); }
Now i can activate and deactivate the gif.
I hope it'll also work in my real program. I'll see.Thank you!
-
@AlexKrammer
Just a small point. @eyllanesc uses a member variable formMovie
. You use a local variable forQMovie *movie = new QMovie(...)
. Be aware that this means you leak aQMovie
. If youron_btn_ON_clicked()
can be called more than once you have no way of releasing the previously-created movie (unless whatever yourGifEffect *effect
is does that for you). And the same leak applies to yourGifEffect *effect = new GifEffect();
, unless yourui->frm_BG->setGraphicsEffect(effect)
looks after that too. Youron_btn_OFF_clicked()
sets that toQ_NULLPTR
, does that release any currentGifEffect
and itsQMovie
?