QThreads and Image loading from Ezust book



  • Hello, I am trying to implement an example that is on the Ezust book to acquire a bit of familiarity with QThreads. The book proposes to implement a sort of simple movie player dividing the problem in two classes: one for visualization and another for the model. The two main classes are as follows:

    #ifndef MOVIEVIEW_H
    #define MOVIEVIEW_H
    
    #include <QMainWindow>
    #include <QLabel>
    #include <QSlider>
    
    class MovieView : public QMainWindow
    {
        Q_OBJECT
    public:
        MovieView();
        ~MovieView();
    public slots:
        void setDelay(int newValue);
        void showPix(const QPixmap* pic);
    signals:
        void intervalChanged(int newValue);
    private:
        QLabel label;
        QSlider slider;
    };
    
    #endif // MOVIEVIEW_H
    

    Implementing

    #include "movieview.h"
    
    void MovieView::showPix(const QPixmap* pic) {
        label->setPixmap(*pic);
    }
    
    void MovieView::setDelay(int newValue) {
        QString str;
        str = QString("%1ms delay between frames").arg(newValue);
        slider->setToolTip(str);
        emit intervalChanged(newValue);
    }
    
    MovieView::MovieView() {
        resize(200, 200);
        slider = new QSlider(Qt::Vertical);
        slider->setRange(1,500);
        slider->setTickInterval(10);
        slider->setValue(100);
        slider->setToolTip("How fast is it spinning?");
        connect(slider, SIGNAL(valueChanged(int)), this,
                SLOT(setDelay(int)));
        QDockWidget *qdw = new QDockWidget("Delay");
        qdw->setWidget(slider);
        addDockWidget(Qt::LeftDockWidgetArea, qdw);
        label = new QLabel("Movie");
        setCentralWidget(label);
    }
    

    And the other class is

    #ifndef MOVIETHREAD_H
    #define MOVIETHREAD_H
    
    #include <QThread>
    #include <QVector>
    #include <QPixmap>
    #include <QString>
    
    class MovieThread
    {
        Q_OBJECT
    public:
        MovieThread();
        ~MovieThread();
        void run();
        void loadPics();
    public slots:
        void stop();
        void addFile(const QString& filename);
        void setInterval(int newDelay);
    signals:
        void show(const QPixmap*);
    private:
        QVector<QPixmap> m_Pics;
        int mDelay;
    };
    
    #endif // MOVIETHREAD_H
    

    implementing

    #include "moviethread.h"
    #include "filevisitor.h"
    
    
    MovieThread::MovieThread()
    {
        loadPics();
    }
    
    void MovieThread::run() {
        int current(0), picCount(m_Pics.size());
        while (true) {
            msleep(m_Delay);
            emit show(&m_Pics[current]);
            current = (current + 1) % picCount;
        }
    }
    
    void MovieThread::stop() {
    terminate();
    wait(5000);
    }
    
    void MovieThread::loadPics() {
        FileVisitor fv("*.png");
        connect (&fv, SIGNAL(foundFile(const QString&)),
                this, SLOT(addFile(const QString&)));
        fv.processEntry(":/images/");
    }
    
    void MovieThread::addFile(const QString& filename) {
        m_Pics << QPixmap(filename);
    }
    
    void MovieThread::setInterval(int newDelay)
    {
        m_Delay = newDelay;
    }
    

    Problem is I needed to implement an additional class in order to browse files

    #ifndef FILEVISITOR_H
    #define FILEVISITOR_H
    
    #include <QDir>
    #include <QObject>
    class FileVisitor : public QObject {
        Q_OBJECT
        public:
            FileVisitor(QString nameFilter="*",
                    bool recursive=true, bool symlinks=false);
        public slots:
            void processFileList(QStringList sl);
            void processEntry(QString pathname);
        signals:
            void foundFile(QString filename);
        protected:
            virtual void processFile(QString filename);
        protected:
            QString m_NameFilter;
            bool m_Recursive;
            QDir::Filters m_DirFilter;
    };
    
    #endif // FILEVISITOR_H
    
    
    void FileVisitor::processFile(QString filename) {
    // qDebug() << QString("FileVisitor::processFile(%1)").arg(filename);
        emit foundFile(filename);
    }
    
    void FileVisitor::processEntry(QString current) {
        QFileInfo finfo(current);
        processEntry(finfo);
    }
    
    void FileVisitor::processEntry(QFileInfo finfo) {
    // qDebug(QString("ProcessEntry: %1").arg(finfo.fileName()));
    if (finfo.isDir()) {
        QString dirname = finfo.fileName();
        if ((dirname==".") || (dirname == ".."))
            return;
        QDir d(finfo.filePath());
        if (skipDir(d))
            return;
        processDir(d);
    } else
        processFile(finfo.filePath());
    }
    
    void FileVisitor::processDir(QDir& d) {
        QStringList filters;
        filters += m_NameFilter;
        d.setSorting( QDir::Name );
        QStringList files = d.entryList(filters, m_DirFilter);
        foreach(QString entry, files) {
             processEntry(d.filePath(entry));
        }
        if (m_Recursive) {
            QStringList dirs = d.entryList(QDir::Dirs);
            foreach (QString dir, dirs) {
                processEntry(d.filePath(dir));
            }
        }
    }
    

    And the main is

    #include <QApplication>
    #include "moviethread.h"
    #include "movieview.h"
    
    int main(int argc, char** argv) {
        QApplication app(argc, argv);
        MovieView view;
        MovieThread movie;
        app.connect(&movie, SIGNAL(show(const QPixmap*)),
                    &view, SLOT(showPix(const QPixmap*)));
        app.connect(&view, SIGNAL(intervalChanged(int)),
                    &movie, SLOT(setInterval(int)));
        app.connect(&app, SIGNAL(aboutToQuit()), &movie, SLOT(stop()));
        movie.start();
        view.show();
        return app.exec();
    }
    

    I have added a resource file in the same folder where the project is and I have added the images in a folder (also located in the project folder) called "images".

    Since I am not very familiar with Threads (I am learning now) I can't get my head around some problems I bumped into: one for all is listed below. It pops up repeatedly for all the connects which are present in the main. Any idea?

    C:\Users\RXD308\QtProjects\Threads\main.cpp:10: error: no matching function for call to 'QApplication::connect(MovieThread*, const char*, MovieView*, const char*)'
                     &view, SLOT(showPix(const QPixmap*)));
                                                         ^


Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.