Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [solved] Why my gif looks like an image ...?
QtWS25 Last Chance

[solved] Why my gif looks like an image ...?

Scheduled Pinned Locked Moved General and Desktop
9 Posts 2 Posters 2.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    Francknos
    wrote on last edited by
    #1

    My gif doesn't work on MyMessageBox *m but it's work on MyMessageBox msg.
    I don't know why. On MyMessageBox *m i see just one image of gif but it's block like an image.

    @
    MyMessageBox msg(this);
    msg.setText(tr("Une reconstruction de la base de donnée est demandé.\nVoulez vous l'effectuer maintenant?"));
    QPixmap p(":/icones/error");
    p=p.scaled(150,150);
    msg.setIconPixmap(p);
    msg.setTextYesButton(tr(" OUI "));
    msg.setTextNoButton(tr(" NON "));
    msg.setFont(QFont("Utsaah",17));
    msg.setSize(700,300);

        if (msg.exec() == MyMessageBox::Accepted)
        {
            MyMessageBox *m = new MyMessageBox(this);
            m->setText(tr("Attendre la fin de la reconstruction de la base de donnée."));
            QMovie *mov = new QMovie(":/gif/wait"); // ????
            m->setStartMovie(mov);
            m->show();
            qApp->processEvents();
            QSqlQuery q;
            q.exec("VACUUM");
            mFile.close();
            if(mFile.open(QIODevice::WriteOnly))
                time <<  QDateTime::currentDateTime().toString("yyyy-MM-dd HH.mm.ss.zzz");
            m->hide();
        }
    

    @

    Here the constructor of MyMessageBox
    @
    MyMessageBox::MyMessageBox(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MyMessageBox)
    {
    ui->setupUi(this);
    this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
    this->setAttribute(Qt::WA_AcceptTouchEvents);
    this->setWindowModality(Qt::WindowModal);
    }
    @

    Méthode setStartMovie
    @
    void MyMessageBox::setStartMovie(QMovie *m)
    {
    ui->label_image->setMovie(m);
    m->start();
    }
    @

    1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by
      #2

      There are several serious problems with this code.
      @
      MyMessageBox msg(this);
      @
      I hope this is a local variable. Otherwise it will most probably crash your app when "this" is destroyed and tries to delete its child.
      @
      MyMessageBox *m = new MyMessageBox(this);
      @
      You are never deleting this so it will live as long as "this" is alive. If you call this entire function more then once you will create several copies of that message box.
      @
      QMovie *mov = new QMovie(":/gif/wait");
      @
      Now you are leaking memory. You never delete this movie object and docs clearly state that the label does NOT take ownership of it.
      @
      qApp->processEvents();
      @
      This will process events ONCE. From there, up to the closing brace, your UI is frozen. This is why you're not seeing any animation. It has nothing to do with whether the MyMessageBox is created on the stack or the heap.

      1 Reply Last reply
      0
      • F Offline
        F Offline
        Francknos
        wrote on last edited by
        #3

        I just want to show a message box during this action :
        @
        QSqlQuery q;
        q.exec("VACUUM");
        @

        To show a messagebox I put :
        @
        MyMessageBox m(this);
        m.setText(tr("Attendre la fin de la reconstruction de la base de donnée."));
        m.show();

        QSqlQuery q;
        q.exec("VACUUM");

        m.hide();
        @

        But the message box appears only if the "VACUUM" takes a lot of time (more than 5 sec)
        It's for that I have added after the show(): @qApp->processEvents();@

        The message works perfectly like this.
        Now I want insert gif but like this:
        @
        MyMessageBox m(this);
        m.setText(tr("Attendre la fin de la reconstruction de la base de donnée."));
        QMovie *mov = new QMovie(":/gif/wait"); // ????
        m.setStartMovie(mov);
        m.show();
        mov->start();

        QSqlQuery q;
        q.exec("VACUUM");

        m.hide();
        delete mov;
        @

        But it dosen't work... with or without @qApp->processEvents();@

        1 Reply Last reply
        0
        • Chris KawaC Offline
          Chris KawaC Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by
          #4

          I can only repeat myself.

          No, the message box does not work perfectly like this. It's just displayed once but it's non-responsive because there's no event loop running between show() and hide(). Have you tried to click a button in it? It won't respond because it's frozen. If your query takes long OS will show your app as non-responsive. There's no event loop so there's no animation either.

          The proper solution is to run your query in a worker thread and show the dialog via exec() instead of show/hide. exec() runs a proper event loop. The dialog will be responsive and your animation will play.
          Before you try it - don't mix exec and the query in the same thread. exec() is blocking so it won't work.

          Btw. you should not delete mov while you're still using it. Check your scopes.

          1 Reply Last reply
          0
          • F Offline
            F Offline
            Francknos
            wrote on last edited by
            #5

            Thanks for your help but how can i do this correctly ?

            @
            MyMessageBox *m = new MyMessageBox(this);
            m->setText(tr("Attendre la fin de la reconstruction de la base de donnée."));
            QMovie *mov = new QMovie(":/gif/wait"); // ????
            m->setStartMovie(mov);
            mov->setParent(m);
            mov->start();
            connect(this, SIGNAL(endVacuum()), m, SLOT(deleteLater()));
            QtConcurrent::run(this, &MainWidget::vacuum);
            m->exec();
            @

            @
            void MainWidget::vacuum()
            {
            QString path ="C:/lastvacuum";
            QFile mFile(path);
            QTextStream time(&mFile);
            QSqlQuery q;
            q.exec("VACUUM");

            if(mFile.open(QIODevice::WriteOnly))
                time <<  QDateTime::currentDateTime().toString("yyyy-MM-dd HH.mm.ss.zzz");
            mFile.close();
            emit endVacuum();
            

            }
            @

            If I do that my gif works but I find it's so complicated just for showing a message to say at the customer that works...

            1 Reply Last reply
            0
            • Chris KawaC Offline
              Chris KawaC Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on last edited by
              #6

              It's not that complicated. A single function that runs asynchronous operation is pretty simple if you ask me.
              It wouldn't look so messy if you encapsulated things properly, eg. put stuff where it belongs:
              @
              //all the other setup should be inside the message box constructor
              //don't construct an object outside of it
              MyMessagebox m(this, tr("Attendre la fin de la reconstruction de la base de donnée."), ":/gif/wait");
              ...
              m.exec();
              @
              and split the vacuum method into something like executeQuery(QString query) and storeTime(QSting fileName).
              Just because something is in one function doesn't make it "easier". It's actually harder, because the next guy who reads it will have to dig through all that boilerplate that could be hidden behind well-named methods. It also makes things harder to reuse and encourages copy/paste programming.
              For example if you create a storeTime method it's quite possible that you can use it somewhere else.
              If you happen to need only to store time and not execute a query you might look at the vacuum() and think "oh, this does what I need but also this other stuff so I can't use it. I'll just copy over the part I need..." and that's bad for maintainability.
              Split your stuff. One function (or class) should do ONE thing. Stuffing everything into one function leads to "Spaghetti code":http://en.wikipedia.org/wiki/Spaghetti_code and "God Objects":http://en.wikipedia.org/wiki/God_object

              1 Reply Last reply
              0
              • F Offline
                F Offline
                Francknos
                wrote on last edited by
                #7

                Normaly MyMessageBox it's simple dialog with button YES/NO.
                But here I want use this Class to do a "popup" message (without any button).
                it's for that I define my text and other attributes.
                It's not the class MyMessageBox which I find complicated, but the method to call vacuum.
                @
                QtConcurrent::run(this, &MainWidget::vacuum);
                @

                1 Reply Last reply
                0
                • Chris KawaC Offline
                  Chris KawaC Offline
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  I don't, so I guess you'll have to get a third opinion to have a democratic result ;)

                  1 Reply Last reply
                  0
                  • F Offline
                    F Offline
                    Francknos
                    wrote on last edited by
                    #9

                    [quote author="Chris Kawa" date="1416575416"]I don't, so I guess you'll have to get a third opinion to have a democratic result ;)[/quote]

                    Anyway it's work with your help. Thanks

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved