0

I would like create a progress bar for user can be see the upload progress. Indeed, today, i use CURL API for upload file on my cloud. But, when i make this, the application crash during the upload. I would like create a progress bar on window (not in CMD). I use an QApplication and create window with progresse barr but, i don't know how refresh the progress barre during the upload.

i discover 2 metode, the function CURLOPT_READFUNCTION and CURLOPT_PROGRESSFUNCTION but, it's don't work for my use(or, i don't know how work this), i use the same function on the example on CURL and i add on argument the class instance for create signal.

Thank's for you help !

After many surch time, i fixe my bug, for the first, i use a new thread for download without crash the graphique application. After, i create an objetct for crete the link between the static fonction for CURL and the signal for make advance the progressbar.

************************** Main.cpp *******************************


#include <QApplication>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

******************** Main Window.cpp ********************************

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "uploadaws.h"
#include "mythread.h"

#include <math.h>

#include <stdio.h>
#include <stdlib.h>
#include "mythread_helper.h"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(this->ui->pushButton,&QPushButton::clicked,this,&MainWindow::actionBouton);
}

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

void MainWindow::actionBouton()
{
    printf("clique \n");
    MyThread *myThread;
    myThread = new MyThread;
    connect(&MyThread::helper,&MyThread_Helper::envoyerInt,this,&MainWindow::avancementSurProgressBar);
    myThread->start();
    //myThread->wait();
}

void MainWindow::avancementSurProgressBar(int valeur)
{
    this->ui->progressBar->setValue(valeur);
}

****************************** My Thread.cpp******************************

#include <QThread>
#include "mythread.h"



MyThread::MyThread(QObject * parent)
{

}



void MyThread::run()
{
    downloadfile();
}

int MyThread::downloadfile()
  {

    CURLcode res;
    QString filename="pi.txt";
    FILE *fp;
    fp = fopen(filename.toStdString().c_str(), "wb");
    CURL *curl_download = curl_easy_init();

    if (curl_download && fp != NULL)
    {
    curl_easy_setopt(curl_download, CURLOPT_URL,"http://www.gecif.net/articles/mathematiques/pi/pi_1_million.txt");
    curl_easy_setopt(curl_download, CURLOPT_WRITEDATA, fp);
    curl_easy_setopt(curl_download, CURLOPT_NOPROGRESS, 0L);
    //progress_bar : the fonction for the progress bar

    curl_easy_setopt(curl_download, CURLOPT_PROGRESSFUNCTION, &MyThread::progress_func);
    //qDebug()<<" Start download"<<endl<<endl;

    res = curl_easy_perform(curl_download);
    //std::cout<<readBuffer<<std::endl;*/
    if (res == CURLE_OK) {
        printf("File downloaded!\n\n");
    } else {
        printf("Transfer failed!");
    }
    double download_speed = 0;
    double timeval = 0;
    double downloadSize = 0;
    curl_easy_getinfo(curl_download, CURLINFO_SIZE_DOWNLOAD, &downloadSize);
    curl_easy_getinfo(curl_download, CURLINFO_TOTAL_TIME, &timeval);
    curl_easy_getinfo(curl_download, CURLINFO_SPEED_DOWNLOAD, &download_speed);
    printf("size: %f, time: %f, download speed: %f\n", downloadSize, timeval, download_speed);

    curl_easy_cleanup(curl_download);
    fclose(fp);
    }
    return 0;
}
int MyThread::progress_func(void* ptr, double TotalToDownload, double NowDownloaded,
                                double TotalToUpload, double NowUploaded)
{

    /*static QProgressBar *pbar;
    pbar =new  QProgressBar(this);
    pbar->setGeometry(10,80,305,30);
    pbar->setTextVisible(true);*/

    //ui->progressBar->setValue(0);

    if(TotalToDownload <= 0.0)
    {
    return 0;
    }
    double fractiondownloaded = NowDownloaded / TotalToDownload;
    double myval =fractiondownloaded*100;
    int progress = static_cast<int>(myval);

    emit helper.emit_signal(progress);
    printf("%d \n",progress);


    return 0;

}
MyThread_Helper MyThread::helper;

************************ MyThread_helper.cpp **************************

#include "mythread.h"

void MyThread_Helper::emit_signal(int val)
{
    test();
    emit envoyerInt(val);
}

*************************** Main Window.h *******************************

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <curl/curl.h>
#include <QProgressBar>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();



public slots :
    void actionBouton();

    void avancementSurProgressBar(int val);



private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

********************* My Thred.h ******************************

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>
#include <curl/curl.h>
#include "mythread_helper.h"

class MyThread : public QThread
{
    Q_OBJECT
public:
    static MyThread_Helper helper;
    MyThread(QObject * parent = 0);
    void run(); // le code du thread
    int downloadfile();
    int progress_func(void* ptr, double TotalToDownload, double NowDownloaded,
                                    double TotalToUpload, double NowUploaded);


private:
signals:
    void envoyerValeurProgress(int val);
};

#endif // MYTHREAD_H

**************************** MyThread helper.h ******************

#ifndef MYTHREAD_HELPER_H
#define MYTHREAD_HELPER_H


#include <QMainWindow>
#include <QObject>

class MyThread_Helper: public QObject
{
    Q_OBJECT
signals:
    void envoyerInt(int val);

public:
    void test()
    {
        int a = 0;
        //envoyerInt(a);
    }
    void emit_signal(int val);
};

#endif // MYTHREAD_HELPER_H

  • Can you show the Qt part of your code ? Do you use QML or Qt Widgets ? – Fryz Feb 23 '22 at 12:59
  • i use QWidget it's jute the code create by QT with slot for the progress barre – vin21207100 Feb 23 '22 at 13:10
  • it's on the header, but, i know how use the signale, my probleme is where i do /can put the emit for advence the progressBar (the link between CURL and the signal for change the value, for create progress bar) (i add my header on my topic) – vin21207100 Feb 23 '22 at 14:07
  • `CURLOPT_PROGRESSFUNCTION but, it's don't work for my use`. "Does not work" is not a problem description. Could you be more specific? The shown code does not attempt to set any progress. – 273K Feb 23 '22 at 15:01
  • yess, i change my code with most simple. When i click on the button, the files was download (or upload) but, the progress bar don''t change and if i add the line ```curl_easy_setopt(curl_download, CURLOPT_NOPROGRESS, FALSE);``` and the application crash. With the debug, i can see it's the emit creates crash (and on the first test, the window crash during the download and rework after) – vin21207100 Feb 23 '22 at 15:35
  • FALSE is of invalid type for CURLOPT_NOPROGRESS that requires long value. You may not pass a non static member function to CURLOPT_PROGRESSFUNCTION. – 273K Feb 24 '22 at 05:26

0 Answers0