CopperSpice Experiments – Pt. 17

October 26, 2020

I’m putting this here because I discovered it while trying to fix a rather horrible “busy” dialog in the Advanced Search portion of Diamond. I had to create a GUI “Hello World” application to test this out so I could file a “simple” bug report. According to the doc animated GIF is supported on all platforms. The code for Linux is a tad behind the documentation.

#include <QApplication>
#include "mainwindow.h"

int main( int argc, char *argv[] )
    QApplication a( argc, argv );

    MainWindow *mw = new MainWindow();


    return a.exec();
#include <QMainWindow>
#include <QMainWindow>
#include <QLabel>
#include <QVBoxLayout>
#include <QMovie>
#include <QByteArray>

class MainWindow : public QMainWindow
    CS_OBJECT( MainWindow )
    MainWindow( QWidget *parent=0 );


    QLabel         *m_hello;
    QLabel         *m_movieLabel;
    QVBoxLayout    *m_layout;
    QWidget        *m_widget;
    QMovie         *m_movie;

#include "mainwindow.h"

MainWindow::MainWindow( QWidget *parent ) :
    QMainWindow( parent )
    qDebug() << "supported formats: " << QMovie::supportedFormats();

    m_hello         = new QLabel( "Hello World!" );
    m_movieLabel    = new QLabel();
    m_movie         = new QMovie( "://animations/spinning-red-diamond-4.gif" );
    m_layout        = new QVBoxLayout();
    m_widget        = new QWidget();

    m_movieLabel->setMovie( m_movie );

    m_layout->addWidget( m_hello );
    m_layout->addWidget( m_movieLabel );

    m_widget->setLayout( m_layout );

    setCentralWidget( m_widget );

    delete m_widget;
    delete m_layout;
    //delete m_movie;
    //delete m_movieLabel;
    //delete m_hello;

When I build and run this on Ubuntu 20.04 LTS I see the following:

No supported formats

A sad sad day indeed.

What this means is the cool animated GIF Icons8 let me create now has to be busted up into frames. Well fine. I just didn’t have anything to do that installed on this system and didn’t want to take the time to learn how to do it in some graphics package because the odds of me having to do it again were slim to none.

A bit of Web searching turned up a really cool site. I didn’t bother to read any of their retention policy, etc. because this was something OpenSource I generated at Icons8. If you have some trade secret images then you have to read that or not use the site.

Once you upload you choose your split options and apparently can do other things.

after upload

Once you click the split button you are quickly greeted with the following:

After split

What is really cool is how they name the files inside of the zip.

files inside of zip

They provide you the decimal number of seconds for each frame. This means you can easily set up your millisecond driven timer. If your brain happens to be too thick to slide the decimal on its own you can just key in

milliseconds to seconds

for the DuckDuckGo search term and you are greeted with:


So, I unzipped into a directory I created called image-work-4. Now I need to fix the file names. I want to get rid of the delay time and prepend “red_diamond_”. In a terminal I cd to the directory and type the following:

rename 's/_delay-0.11s//;' *

This leaves me with a bunch of frame_nn.gif files. There are probably cleaner ways to do the prepend, but here is what I did.

find -L . -type f -name "*.gif" -exec bash -c 'echo "mv $0" "${0%/*}/red_diamond_${0##*/}"' {} \;

That outputs a list of mv commands having both file names with ./ in front of them. I didn’t even try to see if that would work. I just screen scraped them into an editor and replace “./” with “” then scraped the lines from the editor and pasted them into the terminal. After creating a directory underneath my project resources directory I copied in the files.

the files

Honestly I’m created this post because I want to remember the commands. No, rename isn’t a built-in Linux command. It is in the Ubuntu repositories though. That’s a command line ability not all platforms have.

Why am I doing this?

I want to finish this phase of the project. Creating your own animation out of a series of images is very old school. I’ve done it with earlier versions of Qt and even Zinc. It’s actually mandatory on systems without a GPU because most graphics libraries supporting animation require a GPU be present. All you need to know is the value to put in the timer. Every time it fires you move to the next image in the list. After the last image you go back to the first.

When you need to both block the UI and perform a potentially long running task, you toss up a modal dialog with some kind of QFuture or other thread mechanism. Ideally your dialog is frameless with a transparent background so it looks like just your animation is there. When your threaded task ends you connect its ending to the removal of the dialog. Don’t forget to kill off your timer.

<Previous-part Next-part>