Custom network download intermrrent failures



  • I'm new to Qt (and c++) but have had reasonable success until now using the development system (creator 2.4.0). I'm trying to implement a class that downloads (image) data from the web or my local file based on the example in the doc section "here":http://qt-project.org/wiki/Download_Data_from_URL . I then want to display the result as a movie (so I can dispay an animated gif). Since there is no loadFromData function in QMovie I have to implement a custom QIODevice. I based my custom QIODevice on the example "here":http://qt-project.org/wiki/Custom_IO_Device . I tested the two new classes using a bare bones mainwindow application that has only three widget a label to display the result, a lineEdit box to input the URL , and a pushButton to direct the code to obtain the image and display it.

    The problems I'm encountering is that while the code works on an initial request subsequent requests fail after a random number of attempts. In addition when I try to use my new classes in the larger project I'm working on it causes the program to fail when the classes are used in a dialog box when the dialog box is deleted or destoryed. I've tried finding a consistant failure point but have failed. While the code is short and simple I'm unable to post it all since it exceeds the 6000 character post limit.

    I think part of the problem is trying to start a new movie in the loadMovieData function (wich return QByteArray) in the main window since I've verified that there is always data there which I can use in setPixmap to display the first frame of the data loaded but this doesn't explain why the these class cause my program to hang (again intermittently) when used elsewhere when I try to delete a class object (e.g., a dialog box) using these classes.

    MainWindow header:

    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QMovie>
    #include "MovieDevice/moviedownloader.h"
    #include "MovieDevice/moviedevice.h"

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    MovieDevice * md;
    

    private:
    Ui::MainWindow *ui;
    QMovie * movie;
    MovieDownloader * downloadCtrl;

    private slots:
    void loadMovieData();

    void on_pushButton_clicked();
    

    };

    #endif // MAINWINDOW_H
    @

    cpp:

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    movie = new QMovie(this);
    md = new MovieDevice(this);
    downloadCtrl = new MovieDownloader(this);
    // must enable cache in order to display animated gif
    movie->setCacheMode(QMovie::CacheAll);
    }

    MainWindow::~MainWindow()
    {
    delete ui;
    delete movie;
    delete md;
    }

    void MainWindow::loadMovieData(){
    // want to only display a thumbnail image so have to resize the movie(image) data
    // need to use QPixMap to get the movie size since it hasn't run yet
    QPixmap tempImage;
    tempImage.loadFromData(downloadCtrl->downloadedMovie());
    QSize size;
    size.setHeight(tempImage.height());
    size.setWidth(tempImage.width());
    size.scale(400,100,Qt::KeepAspectRatio);

    // QMovie dosen't reset things when the QIODevice is set
    // when the new device is the same as the old one
    // so define a dummy device for movie so that
    // the when new data is available it will be read by movie
    // (necessary kludge to prevent memory leaks)
    MovieDevice * am = new MovieDevice();
    movie->stop();
    // kludge to reset movie data
    movie->setDevice(am);
    // get the actual data
    md->setMovieData(downloadCtrl->downloadedMovie());
    // reset back to the old device and delete the dummy device
    movie->setDevice(md);
    delete am;
    // scale the movie to thumbnail size
    movie->setScaledSize(size);
    // check that this is a valid movie
    // if valid display the thumbnail
    // if not valid display an error image
    if(movie->isValid()){
        movie->start();
        ui->label->setMovie(movie);
    }else{
        tempImage.load(":/base/IMAGES/noImage.png");
        ui->label->setPixmap(tempImage);
    }
    

    }

    void MainWindow::on_pushButton_clicked()
    {
    movie->stop();
    movie->setFileName(":/base/IMAGES/image-loading.gif");
    QSize size;
    size.setHeight(100);
    size.setWidth(100);
    movie->setScaledSize(size);
    movie->start();
    ui->label->setMovie(movie);
    QUrl movieURL(ui->lineEdit->text());
    downloadCtrl->startNewDownload(movieURL);
    connect(downloadCtrl,SIGNAL(downLoaded()),this,SLOT(loadMovieData()));
    }
    @



  • I have the class code availble to post but am unsure of the posting rules for adding this code in a reply. The download class header is 33 lines and the download cpp is 26 lines of code. The custon QIODevice header is 37 lines and the cpp is 64 lines of code. I'll post it if requested.



  • Problem solved. I had to create two QMovie objects and alternate there use. Several people locally to me expressesd interest in my solution. Rather than send out an email to each perrson I posted my solution as "Using Qt to display a WEB animated gif":http://getoddnews.com/2012/07/08/using-qt-to-display-a-web-animated-gif/ on my website for them and anyone else who may be interested.


Log in to reply
 

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