Unsolved There is one segment when play gif with movie
-
Any body has this problem?
code is below, I just want play gif cyclem_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. -
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:
-
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!