Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Italian
  4. Download dei files in apertura finestra
Forum Updated to NodeBB v4.3 + New Features

Download dei files in apertura finestra

Scheduled Pinned Locked Moved Unsolved Italian
9 Posts 3 Posters 1.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    fermatqt
    wrote on last edited by
    #1

    ciao!

    prendendo spunto da un articolo trovato online, ho creato questa classe che dovrebbe scaricare il file dal web:

    #include "downloadydl.h"
    
    DownloadYdl::DownloadYdl() {}
    
    void DownloadYdl::fileDownloaded(QNetworkReply* np) {
        dd = np->readAll();
        np->deleteLater();
        emit downloaded();
    }
    
    void DownloadYdl::download() {
        connect(&am, SIGNAL(finished(QNetworkReply*)), this, SLOT(fileDownloaded(QNetworkReply*)));
        QUrl url(remotePath);
        QNetworkRequest request(url);
        am.get(request);
    }
    
    bool DownloadYdl::check() {
        QString strFile = "";
    
    #ifdef W_OS_LINUX
        strFile = "./ydl";
        remotePath = "https://.........";
    #else
        strFile = "./ydl.exe";
        remotePath = "https://.......";
    #endif
    
        QFile file(strFile);
        return QFileInfo::exists(strFile);
    }
    
    QByteArray DownloadYdl::downloadedData() const {
        return dd;
    }
    

    in avvio di programma, lancio metodo check per vedere se il file già esiste.
    e se non esiste lancio il download.
    solo che apparentemente il file non viene scaricato.

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
        ui->setupUi(this);
        check();
    }
    
    MainWindow::~MainWindow() {
        delete ui;
    }
    
    void MainWindow::check() {
        ydl = new DownloadYdl();
        if(!ydl->check()) {
            qDebug() << "KO";
            ydl->download();
            qDebug() << "FATTO";
        }
    }
    

    probabilmente sbaglio qui qualcosa sugli SLOT/SIGNAL.

    1 Reply Last reply
    0
    • Rcc21R Offline
      Rcc21R Offline
      Rcc21
      wrote on last edited by Rcc21
      #2

      Il problema e' che non stai connettendo i segnali emessi dalla classe DownloadYdl.

      Nella funzione MainWindow::check() dopo la creazione di ydl, devi collegare il segnale DownloadYdl::downloaded con uno slot che devi dichiarare nella MainWindow. In tale slot dovrai chiamare la funzione DownloadYdl::downloadedData() che in caso positivo dovrebbe contenere il tuo file. Ti consiglio di controllare la documentazione signal/slot per aggiungere la QObject::connect

      Nota: attualmente nella funzione MainWindow::check() c'e' un memory leak, infatti ogni volta che chiami la funzione viene allocata di nuovo la classe DownloadYdl, sposta questa allocazione, ed eventuale connect, nel costruttore.

      1 Reply Last reply
      0
      • F Offline
        F Offline
        fermatqt
        wrote on last edited by
        #3

        ciao!

        allora, ho fatto un pò di modifiche:

        #include "downloadydl.h"
        
        DownloadYdl::DownloadYdl() {
            if(!check()) {
                connect(&am, SIGNAL(finished(QNetworkReply*)), this, SLOT(fileDownloaded(QNetworkReply*)));
                QUrl url(remotePath);
                QNetworkRequest request(url);
                am.get(request);
            }
        }
        
        DownloadYdl::~DownloadYdl() {}
        
        void DownloadYdl::fileDownloaded(QNetworkReply* np) {
            dd = np->readAll();
            np->deleteLater();
            emit downloaded();
        }
        
        QByteArray DownloadYdl::downloadedData() const {
            qDebug() << dd;
            qDebug() << remotePath;
            return dd;
        }
        
        bool DownloadYdl::check() {
            QString strFile = "";
        
        #ifdef __linux__
            strFile = "./ydl";
            remotePath = "https://yt-dl.org/downloads/latest/youtube-dl";
        #else
            strFile = "./ydl.exe";
            remotePath = "https://yt-dl.org/downloads/latest/youtube-dl.exe";
        #endif
        
            QFile file(strFile);
            return QFileInfo::exists(strFile);
        }
        

        il controllo l'ho spostato qua.
        poi nella mainwindow:

        #include "mainwindow.h"
        #include "ui_mainwindow.h"
        
        MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
            ui->setupUi(this);
            ydl = new DownloadYdl();
            connect(ydl, SIGNAL(downloaded()), this, SLOT(download()));
        }
        
        MainWindow::~MainWindow() {
            delete ui;
        }
        
        void MainWindow::download() {
            ydl->downloadedData();
        }
        

        creando lo slot come mi hai detto:

        private slots:
            void download();
        

        in console mi esce questo:

        "302"
        "https://yt-dl.org/downloads/latest/youtube-dl"
        

        ma il file non viene scaricato.

        1 Reply Last reply
        0
        • Rcc21R Offline
          Rcc21R Offline
          Rcc21
          wrote on last edited by
          #4

          Perche' il contenuto del file e' all'interno del QByteArray ritornato dalla funzione DownloadYdl::downloadedData(). Nella funzione MainWindow::download() devi creare tu il file e popolarlo con il valore ritornato da ydl->downloadedData();.

          Ti allego uno snippet:

          {
              QFile file(fileName);
          
              if (!file.open(QFile::WriteOnly)) {
                 // Errore in apertura file
                  return false;
              }
          
              auto data = ydl->downloadedData();
              file.write(data);
              file.close();
              return true;
          }
          
          1 Reply Last reply
          0
          • F Offline
            F Offline
            fermatqt
            wrote on last edited by
            #5

            ok grazie, ho apportato queste modifiche e ha funzionato:

            #include "downloadydl.h"
            
            DownloadYdl::DownloadYdl() {
            #ifdef __linux__
                remotePath = "https://yt-dl.org/downloads/latest/youtube-dl";
            #else
                remotePath = "https://yt-dl.org/downloads/latest/youtube-dl.exe";
            #endif
            
                connect(&am, SIGNAL(finished(QNetworkReply*)), this, SLOT(fileDownloaded(QNetworkReply*)));
                QUrl url = QUrl::fromEncoded(remotePath.toLocal8Bit());
                QNetworkRequest request(url);
                am.get(request);
            }
            
            DownloadYdl::~DownloadYdl() {}
            
            void DownloadYdl::fileDownloaded(QNetworkReply* np) {
                dd = np->readAll();
                np->deleteLater();
                emit downloaded();
            }
            
            QByteArray DownloadYdl::downloadedData() const {
                return dd;
            }
            

            nella gui:

            #include "mainwindow.h"
            #include "ui_mainwindow.h"
            
            MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
                ui->setupUi(this);
                
            #ifdef __linux__
                strFile = "./ydl";
            #else
                strFile = "./ydl.exe";
            #endif
                
                if(!check()) {
                    ydl = new DownloadYdl();
                    connect(ydl, SIGNAL(downloaded()), this, SLOT(download()));
                }
            }
            
            MainWindow::~MainWindow() {
                delete ui;
            }
            
            bool MainWindow::check() {
                QFile file(strFile);
                return QFileInfo::exists(strFile);
            }
            
            void MainWindow::download() {
                QFile file(strFile);
                
                if (!file.open(QFile::WriteOnly)) {
                    qDebug() << "ERRORE";
                }
                
                auto data = ydl->downloadedData();
                file.write(data);
                file.close();
            }
            

            intanto grazie mille per le dritte!!

            1 Reply Last reply
            0
            • F Offline
              F Offline
              fermatqt
              wrote on last edited by fermatqt
              #6

              no scusa, come non detto.
              mi crea un file, ma dentro al file mi scrive 302.

              io ho visto che 302 dovrebbe essere il codice HTTP relativo al redirect.
              come se non trovasse l'url, ma se lo metti nel browser lo trova senza problemi.

              ho fatto una modifica:

              void DownloadYdl::onFinished(QNetworkReply* np) {
                  QVariant statusCode = np->attribute(QNetworkRequest::HttpStatusCodeAttribute);
                  qDebug() << statusCode;
              
                  switch(reply->error()) {
                  case QNetworkReply::NoError:
                      qDebug() << "No errori";
                      break;
                  default:
                      qDebug() << reply->errorString().toLatin1();
                      break;
                  }
              
                  dd = np->readAll();
                  np->deleteLater();
                  emit downloaded();
              }
              

              questo mi risponde così:

              QVariant(int, 302)
              No errori
              
              Rcc21R 1 Reply Last reply
              0
              • F fermatqt

                no scusa, come non detto.
                mi crea un file, ma dentro al file mi scrive 302.

                io ho visto che 302 dovrebbe essere il codice HTTP relativo al redirect.
                come se non trovasse l'url, ma se lo metti nel browser lo trova senza problemi.

                ho fatto una modifica:

                void DownloadYdl::onFinished(QNetworkReply* np) {
                    QVariant statusCode = np->attribute(QNetworkRequest::HttpStatusCodeAttribute);
                    qDebug() << statusCode;
                
                    switch(reply->error()) {
                    case QNetworkReply::NoError:
                        qDebug() << "No errori";
                        break;
                    default:
                        qDebug() << reply->errorString().toLatin1();
                        break;
                    }
                
                    dd = np->readAll();
                    np->deleteLater();
                    emit downloaded();
                }
                

                questo mi risponde così:

                QVariant(int, 302)
                No errori
                
                Rcc21R Offline
                Rcc21R Offline
                Rcc21
                wrote on last edited by
                #7

                @fermatqt

                Il problema e' che quel link non punta al contenuto del file, ma ad un link per scaricarlo. In sostanza quello che tu stai richiedendo e' il contenuto di quel link che e' 302, se invece richiedi un link che contiene effettivamente qualcosa allora tutto funziona:

                #include <QCoreApplication>
                #include <QDebug>
                #include <QFile>
                #include <QNetworkAccessManager>
                #include <QNetworkReply>
                
                int main(int argc, char* argv[])
                {
                    QCoreApplication a(argc, argv);
                
                    QNetworkAccessManager nam;
                    QObject::connect(&nam, &QNetworkAccessManager::finished, [&](QNetworkReply* reply) {
                        if (!reply) {
                            qDebug() << "Null reply";
                            a.exit(1);
                            return;
                        }
                
                        QFile f(QCoreApplication::applicationDirPath() + "/dl.jpg");
                
                        if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
                            qDebug() << "Failed to open file";
                            a.exit(1);
                            return;
                        }
                
                        f.write(reply->readAll());
                        f.close();
                        reply->deleteLater();
                
                        a.exit(0);
                    });
                    QNetworkRequest request(QUrl("https://media.geeksforgeeks.org/wp-content/uploads/20190719161411/cat1-225x300.jpg"));
                    nam.get(request);
                
                    return a.exec();
                }
                

                Ti direi di fare una prova con una immagine per capire se la tua logica funziona correttamente, poi provi con il tuo link.

                Se quello che desideri e' un effetto stile browser, credo ci sia da cambiare completamente l'approccio.

                1 Reply Last reply
                0
                • F Offline
                  F Offline
                  fermatqt
                  wrote on last edited by
                  #8

                  ciao.

                  guarda, ho usato quel link per fare delle prove con wget, curl e un programmino scritto in java.
                  e funziona senza problemi.

                  allora ho copiato quel file su un altro server, e ho fatto una prova da li.
                  e il codice ha funzionato.
                  evindentemente Qt ha qualche problema con quel server specifico.

                  allora ho provato ad usare QProcess:

                      process = new QProcess();
                      if (process) {
                          process->setEnvironment(QProcess::systemEnvironment());
                          process->setProcessChannelMode(QProcess::MergedChannels);
                          process->start("wget https://yt-dl.org/downloads/latest/youtube-dl -O ydl");
                          process->waitForStarted();
                          connect(process, &QProcess::readyReadStandardOutput, this, &MainWindow::readOutput);
                          connect(process, &QProcess::readyReadStandardError, this, &MainWindow::readError);
                      }
                  

                  questo codice funziona.
                  è il download diretto a quel link che non funziona.
                  non so se mi sono spiegato.

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    GersonHdez
                    Banned
                    wrote on last edited by
                    #9
                    This post is deleted!
                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved