Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

There is one segment when play gif with movie



  • Any body has this problem?
    code is below, I just want play gif cycle

    m_app = new QApplication(argc, args);
    QWidget w;
        w.show();
    QLabel label(w);
        QMovie movie(file);
        label.setMovie(&movie);
        movie.start();
        label.show();
        time_t t = time(NULL);
        int c = 0;
        printf("movie cycle show\n");
        while (true) {
            m_app->eventDispatcher();
            m_app->processEvents();
            if (time(NULL) - t > 30000) {
                break;
            }
            if (c++ % 100000 == 0) {
                c = 1;
            }
            if (movie.state() == QMovie::NotRunning) {
    //            printf("movie status changed to rerun\n");
                movie.start();
            }
        }
    

    and gdb give this:

    (gdb) bt full
    #0  0x414c7044 in __memcpy_neon () from /lib/libc.so.6
    No symbol table info available.
    #1  0x409371f8 in QImage::copy (this=0xc8b84, r=...) at image/qimage.cpp:1154
            ss = 0x41fd5008 '\377' <repeats 200 times>...
            dd = 0x41dd1008 '\377' <repeats 200 times>...
            image = {<QPaintDevice> = {
                _vptr.QPaintDevice = 0x40d8520c <vtable for QImage+8>, 
                painters = 0, reserved = 0x0}, d = 0xfda98}
            x = -1090522388
            y = 820584
            w = 808376
            h = 1
            dx = 0
            dy = 0
            image = warning: can't find linker symbol for virtual table for `QImage' value
    warning:   found `QImageIOHandler::device() const' instead
    {<QPaintDevice> = {
                _vptr.QPaintDevice = 0x40955c10 <QImageIOHandler::device() const+24>, painters = 56356, reserved = 0xc8b18}, d = 0xbefff27c}
            pixels_to_copy = -1090522372
            lines_to_copy = 820584
            byteAligned = false
    #2  0x40936f4c in QImage::detach (this=0xc8b84) at image/qimage.cpp:1079
    No locals.
    #3  0x4097d378 in QRasterPlatformPixmap::createPixmapForImage (this=0xc8b58, 
    ---Type <return> to continue, or q <return> to quit---
        sourceImage=..., flags=..., inPlace=false) at image/qpixmap_raster.cpp:341
            format = QImage::Format_RGB32
    #4  0x4097c5f4 in QRasterPlatformPixmap::fromImage (this=0xc8b58, 
        sourceImage=..., flags=...) at image/qpixmap_raster.cpp:146
            image = {<QPaintDevice> = {
                _vptr.QPaintDevice = 0x40d8520c <vtable for QImage+8>, 
                painters = 0, reserved = 0x0}, d = 0xc8568}
    #5  0x40971514 in QPixmap::fromImage (image=..., flags=...)
        at image/qpixmap.cpp:1606
            data = {d = 0xc8b58}
    #6  0x40978634 in QMoviePrivate::infoForFrame (this=0xc8238, frameNumber=131)
        at image/qmovie.cpp:379
            anImage = {<QPaintDevice> = {
                _vptr.QPaintDevice = 0x40d8520c <vtable for QImage+8>, 
                painters = 0, reserved = 0x0}, d = 0xc8568}
            aPixmap = {<QPaintDevice> = {_vptr.QPaintDevice = 0xbefff46c, 
                painters = 1, reserved = 0xb39c1bc5}, data = {d = 0x41570000}}
            aDelay = 0
    #7  0x409788f0 in QMoviePrivate::next (this=0xc8238) at image/qmovie.cpp:439
            time = {mds = 18152389}
            info = {pixmap = {<QPaintDevice> = {_vptr.QPaintDevice = 0x88378, 
                  painters = 63488, reserved = 0x88378}, data = {d = 0x0}}, 
              delay = 0, endMark = 48}
    ---Type <return> to continue, or q <return> to quit---
            scaledSize = {wd = 0, ht = 1}
            processingTime = 566572
    #8  0x40978c04 in QMoviePrivate::_q_loadNextFrame (this=0xc8238, 
        starting=false) at image/qmovie.cpp:490
            q = 0xbefffa68
    #9  0x40978bcc in QMoviePrivate::_q_loadNextFrame (this=0xc8238)
        at image/qmovie.cpp:484
    No locals.
    #10 0x40979f14 in QMovie::qt_static_metacall (_o=0xbefffa68, 
        _c=QMetaObject::InvokeMetaMethod, _id=12, _a=0xbefff6a8)
        at .moc/moc_qmovie.cpp:164
            _t = 0xbefffa68
    #11 0x4102b9b8 in QMetaObject::activate(QObject*, int, int, void**) ()
       from /usr/local/qt5-arm/lib/libQt5Core.so.5
    No symbol table info available.
    #12 0x41038808 in QTimer::timerEvent(QTimerEvent*) ()
       from /usr/local/qt5-arm/lib/libQt5Core.so.5
    No symbol table info available.
    #13 0x4102c708 in QObject::event(QEvent*) ()
       from /usr/local/qt5-arm/lib/libQt5Core.so.5
    No symbol table info available.
    #14 0x4012a37c in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
       from /usr/local/qt5-arm/lib/libQt5Widgets.so.5
    

    Can anybody give some advice? It's in armv7, and linux-4.9
    And it will run for some seconds, less then one minute, and then give segment fault.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Why not just start the event loop like for any Qt GUI application ?



  • Sorry, what event loop do you mean? And how to write?



  • @jmdvirus said in There is one segment when play gif with movie:

    And how to write?

    Your application is not really "Qt conform", you can try this way:

    m_app = new QApplication(argc, args);
    QWidget w;
        w.show();
    QLabel label(w);
        QMovie movie(file);
        
        // to restart the movie
        QObject::connect(&movie, &QMovie::finished, m_app, [=]()
        {
            printf("rerun movie\n");
            movie.start();
        }
        );
        label.setMovie(&movie);
        movie.start();
        label.show();
        printf("movie cycle show\n");
    
        // start the event queue processing...
        m_app->exec();
    
    

    I would also suggest you to read at least those articles:


  • Lifetime Qt Champion

    To add to @KroMignon, m_app should be on the stack, there's no need to allocate it on the heap.



  • Oh, yes, thank you. But I just use another way to do it

    class MovieTest : public QWidget {
            Q_OBJECT
        public:
            explicit MovieTest(QWidget *parent = NULL) {
                this->setParent(parent);
                connect(&m_movie, SIGNAL(finished()), this, SLOT(restartMovie()));
            }
    
            int init(const char *file) {
                m_movie.setFileName(file);
                return 0;
            }
    
            int start() {
                m_label.setMovie(&m_movie);
                m_movie.start();
                return 0;
            }
    
        public slots:
                    void restartMovie() {
                printf("move status: [%d]\n", m_movie.state());
                m_movie.start();
            };
    
        protected:
            bool event(QEvent *event) override {
                printf("--------- get event ???[%d]\n", event->type());
                printf("move status [%d]\n", m_movie.state());
            }
    
        private:
            QMovie   m_movie;
            QLabel   m_label;
    };
    

    But the segment also exist



  • @jmdvirus First, always call base class constructor in you constructor, and prefere new connect syntax to detect possible typo errors on build time:

    explicit MovieTest(QWidget *parent = NULL): QWidget(parent)
           {
                connect(&m_movie, &QMovie::finished, this, &MovieTest::restartMovie);
            }
    

    Second, how to do you have changed the main() function?



  • I move connect to init function, and then change main to below

    QApplication app(argc, args);
    
      printf("Start to show\n");
      MovieTest m;
      m.init(args[1]);
      m.start();
      m.show();
    
      app.exec();
    

    but problem is also exist, any other need change?



  • @jmdvirus Do you have change the constructor?

    Because I am lazy, I made a little google search and found this => https://doc.qt.io/qt-5/qtwidgets-widgets-movie-example.html

    I think this is a good starting point for you and will help you to understand what you are doing wrong.



  • No, show is normal, it will segment fault after show some times
    This may help to know

    # test_qt_tips bootLoading.gif 
    Start program
    Start to show
    move status: [0]
    move status: [0]
    Segmentation fault
    

    "move status" means restart show movie, but it will segment fault after how many times is unsure, maybe more, or less.

    construct like this

    explicit MovieTest(QWidget *parent = NULL) {
                this->setParent(parent);
                m_label.setParent(this);
            }
    
            int init(const char *file) {
                m_movie.setFileName(file);
                connect(&m_movie, SIGNAL(finished()), this, SLOT(restartMovie()));
                return 0;
            }
    


  • @jmdvirus Because I am a lazy developer, I made a little Google search and found this ==> https://doc.qt.io/qt-5/qtwidgets-widgets-movie-example.html.

    I think this is a good starting point for you application and I will help your to understand what you may have do wrong.



  • ok, thank you!


Log in to reply