Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Problem with QThread
Forum Updated to NodeBB v4.3 + New Features

Problem with QThread

Scheduled Pinned Locked Moved Unsolved General and Desktop
2 Posts 2 Posters 156 Views 1 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.
  • S Offline
    S Offline
    Stefanoxjx
    wrote on last edited by Stefanoxjx
    #1

    Hello guys, I have a problem with QThread.
    I have a class that copies some files, and during this operation, I would like to update a progress bar in a QDialog.
    I tried running the copy method on a thread, but the QDialog only appears at the end of the file copy.
    Where am I going wrong?
    Thanks.

    Ciao.

    backup.h

    class CopyData : public QObject
    {
        Q_OBJECT
    
    public:
        CopyData();
         ~CopyData() {};
    
    public slots:
        void sltExecuteCopy(QString sourceDir, QString destDir);
    
    signals:
        void sigProgress(QString fileName, uint32_t fileCount);
        void sigCopyEnded(void);
    };
    
    
    class Backup : public QObject
    {
        Q_OBJECT
    
    public:
        Backup();
        ~Backup() {delete this;}
    
    private:
        //Variabili
        QString       BackupDestDir, SavedName;
    
        //QMessageBox   *WaitDbBackup, *WaitCertsBackup;
        QDialog       *dlgBackup;
        QLabel        *lblBackup;
        QProgressBar  *pbBackupCerts;
        QTextEdit     *teBackupCerts;
        CopyData      *cd;
        QThread       *cdThread;
    
    //protected:
    //    void showEvent(QShowEvent *event) override;
    
    private slots:
        void    sltBackupFinished(void);
        void    sltUpdateProgress(QString fileName, uint32_t fileCount);
        void    sltBackupCertsEnded(void);
    
    signals:
        void sigStartCertsBackup(void);
        void sigDialogShowed(QString srcDir, QString destDir);
    };
    

    backup.cpp

    Backup::Backup(void)
    {
        dlgDbBackup = new QDialog(this);
        QVBoxLayout *vlMain = new QVBoxLayout(dlgDbBackup);
    
        dlgDbBackup->setLayout(vlMain);
        QLabel *lblBackup = new QLabel("Some pre operations...");
        vlMain->addWidget(lblBackup);
    
        QPushButton btnGo = new QPushButton("Go", this);
        connect(btnGo, &QPushButton::clicked, this, &Backup::sltBackupEnded);
        vlMain->addWidget(btnStop);
    
        dlgDbBackup->exec();
    }
    
    /* Grrrrr!!! Doesn't work!!!
    void DbBackup::showEvent(QShowEvent *event)
    {
        DbBackup::showEvent(event);
        cdThread->start();
        QMetaObject::invokeMethod(cd, "sltExecuteCopy", Qt::DirectConnection,
                                  Q_ARG(QString, "pippo"),
                                  Q_ARG(QString, "pluto"));
    
    }*/
    
    void Backup::sltBackupEnded(void)
    {
        delete dlgDbBackup;
    
        int exitCode = 0; //for debug only
        
        if(exitCode != 0)
        {
            QMessageBox::critical(this, "Backup", "Backu problem");
            return;
        }
        else
        {
    //        CopyMade = true;
            QMessageBox MsgBox;
            MsgBox.setWindowTitle("Backup");
            MsgBox.setText("Pre operations ok, do you want to proceed?");
            MsgBox.setIcon(QMessageBox::Question);
            MsgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
            QAbstractButton *BtnYes = MsgBox.button(QMessageBox::Yes);
            BtnYes->setText("Si");
            QAbstractButton *BtnNo = MsgBox.button(QMessageBox::No);
            BtnNo->setText("No");
            MsgBox.exec();
    
            if(MsgBox.clickedButton() == BtnNo) return;
        }
    
        QString srcDir = //source path
        QString destDir = //Destination path
        srcDir.replace(R"(\\)", "/").replace(R"(\)", "/");
        destDir.replace(R"(\\)", "/").replace(R"(\)", "/");;
    
        Dir.mkdir(destDir);
    
        QDialog *dlgBackupCerts = new QDialog(this);
        QVBoxLayout *vlMain = new QVBoxLayout(dlgBackupCerts);
        dlgBackupCerts->setLayout(vlMain);
    
        pbBackupCerts = new QProgressBar(this);
        pbBackupCerts->setRange(0, totFiles);
        vlMain->addWidget(pbBackupCerts);
    
        teBackupCerts = new QTextEdit(this);
        vlMain->addWidget(teBackupCerts);
    
        cd = new CopyData;
        cdThread = new QThread(this);
    
        connect(cd, &CopyData::sigProgress, this, &DbBackup::sltUpdateProgress);// DialogoAggiornabile::aggiornaEtichetta);
        connect(cd, &CopyData::sigCopyEnded, this, &DbBackup::sltBackupCertsEnded);
    
        cd->moveToThread(cdThread);
    
    
    //        cdThread->start();
    //        QMetaObject::invokeMethod(cd, "sltExecuteCopy", Qt::DirectConnection,
    //                                  Q_ARG(QString, srcDir),
    //                                  Q_ARG(QString, destDir));
    
    
        dlgBackupCerts->show();
    
        cdThread->start();
        QMetaObject::invokeMethod(cd, "sltExecuteCopy", Qt::DirectConnection,
                                      Q_ARG(QString, srcDir),
                                      Q_ARG(QString, destDir));
    
    }
    
    void Backup::sltUpdateProgress(QString fileName, uint32_t fileCount)
    {
        pbBackupCerts->setValue(fileCount);
        teBackupCerts->append(fileName);
    }
    
    void Backup::sltBackupCertsEnded(void)
    {
        cdThread->quit();
        cdThread->wait();
    }
    
    
    CopyData::CopyData() //QString srcDir, QString destDir)
    {
        qDebug() << "Constructor";
    }
    
    
    void CopyData::sltExecuteCopy(QString srcDir, QString destDir)
    {
        QDir sourceDirectory(srcDir);
        QDir destinationDirectory(destDir);
    
        uint32_t i = 0;
        foreach(QString directoryName, sourceDirectory.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
        {
            destinationDirectory.mkpath(destDir+"/"+directoryName);
            QString destinationPath = destDir+"/"+directoryName;
            destinationDirectory.mkpath(destinationPath);
    
            QDir currentSrcDir(srcDir + "/" + directoryName);
            qDebug() << currentSrcDir;
    
            foreach(QString fileName, currentSrcDir.entryList(QDir::Files))
            {
                qDebug() << i << srcDir+"/"+directoryName+"/"+fileName << "--->" << destDir+"/"+directoryName+"/"+fileName;
                QFile::copy(srcDir+"/"+directoryName+"/"+fileName, destDir+"/"+directoryName+"/"+fileName);
                emit sigProgress(fileName, ++i);
            }
        }
    
    //    QDir finalDestination(destDir); //cantiere: gestire errori
    //    finalDestination.refresh();
    
        emit sigCopyEnded();
    }
    
    
    Christian EhrlicherC 1 Reply Last reply
    0
    • S Stefanoxjx

      Hello guys, I have a problem with QThread.
      I have a class that copies some files, and during this operation, I would like to update a progress bar in a QDialog.
      I tried running the copy method on a thread, but the QDialog only appears at the end of the file copy.
      Where am I going wrong?
      Thanks.

      Ciao.

      backup.h

      class CopyData : public QObject
      {
          Q_OBJECT
      
      public:
          CopyData();
           ~CopyData() {};
      
      public slots:
          void sltExecuteCopy(QString sourceDir, QString destDir);
      
      signals:
          void sigProgress(QString fileName, uint32_t fileCount);
          void sigCopyEnded(void);
      };
      
      
      class Backup : public QObject
      {
          Q_OBJECT
      
      public:
          Backup();
          ~Backup() {delete this;}
      
      private:
          //Variabili
          QString       BackupDestDir, SavedName;
      
          //QMessageBox   *WaitDbBackup, *WaitCertsBackup;
          QDialog       *dlgBackup;
          QLabel        *lblBackup;
          QProgressBar  *pbBackupCerts;
          QTextEdit     *teBackupCerts;
          CopyData      *cd;
          QThread       *cdThread;
      
      //protected:
      //    void showEvent(QShowEvent *event) override;
      
      private slots:
          void    sltBackupFinished(void);
          void    sltUpdateProgress(QString fileName, uint32_t fileCount);
          void    sltBackupCertsEnded(void);
      
      signals:
          void sigStartCertsBackup(void);
          void sigDialogShowed(QString srcDir, QString destDir);
      };
      

      backup.cpp

      Backup::Backup(void)
      {
          dlgDbBackup = new QDialog(this);
          QVBoxLayout *vlMain = new QVBoxLayout(dlgDbBackup);
      
          dlgDbBackup->setLayout(vlMain);
          QLabel *lblBackup = new QLabel("Some pre operations...");
          vlMain->addWidget(lblBackup);
      
          QPushButton btnGo = new QPushButton("Go", this);
          connect(btnGo, &QPushButton::clicked, this, &Backup::sltBackupEnded);
          vlMain->addWidget(btnStop);
      
          dlgDbBackup->exec();
      }
      
      /* Grrrrr!!! Doesn't work!!!
      void DbBackup::showEvent(QShowEvent *event)
      {
          DbBackup::showEvent(event);
          cdThread->start();
          QMetaObject::invokeMethod(cd, "sltExecuteCopy", Qt::DirectConnection,
                                    Q_ARG(QString, "pippo"),
                                    Q_ARG(QString, "pluto"));
      
      }*/
      
      void Backup::sltBackupEnded(void)
      {
          delete dlgDbBackup;
      
          int exitCode = 0; //for debug only
          
          if(exitCode != 0)
          {
              QMessageBox::critical(this, "Backup", "Backu problem");
              return;
          }
          else
          {
      //        CopyMade = true;
              QMessageBox MsgBox;
              MsgBox.setWindowTitle("Backup");
              MsgBox.setText("Pre operations ok, do you want to proceed?");
              MsgBox.setIcon(QMessageBox::Question);
              MsgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
              QAbstractButton *BtnYes = MsgBox.button(QMessageBox::Yes);
              BtnYes->setText("Si");
              QAbstractButton *BtnNo = MsgBox.button(QMessageBox::No);
              BtnNo->setText("No");
              MsgBox.exec();
      
              if(MsgBox.clickedButton() == BtnNo) return;
          }
      
          QString srcDir = //source path
          QString destDir = //Destination path
          srcDir.replace(R"(\\)", "/").replace(R"(\)", "/");
          destDir.replace(R"(\\)", "/").replace(R"(\)", "/");;
      
          Dir.mkdir(destDir);
      
          QDialog *dlgBackupCerts = new QDialog(this);
          QVBoxLayout *vlMain = new QVBoxLayout(dlgBackupCerts);
          dlgBackupCerts->setLayout(vlMain);
      
          pbBackupCerts = new QProgressBar(this);
          pbBackupCerts->setRange(0, totFiles);
          vlMain->addWidget(pbBackupCerts);
      
          teBackupCerts = new QTextEdit(this);
          vlMain->addWidget(teBackupCerts);
      
          cd = new CopyData;
          cdThread = new QThread(this);
      
          connect(cd, &CopyData::sigProgress, this, &DbBackup::sltUpdateProgress);// DialogoAggiornabile::aggiornaEtichetta);
          connect(cd, &CopyData::sigCopyEnded, this, &DbBackup::sltBackupCertsEnded);
      
          cd->moveToThread(cdThread);
      
      
      //        cdThread->start();
      //        QMetaObject::invokeMethod(cd, "sltExecuteCopy", Qt::DirectConnection,
      //                                  Q_ARG(QString, srcDir),
      //                                  Q_ARG(QString, destDir));
      
      
          dlgBackupCerts->show();
      
          cdThread->start();
          QMetaObject::invokeMethod(cd, "sltExecuteCopy", Qt::DirectConnection,
                                        Q_ARG(QString, srcDir),
                                        Q_ARG(QString, destDir));
      
      }
      
      void Backup::sltUpdateProgress(QString fileName, uint32_t fileCount)
      {
          pbBackupCerts->setValue(fileCount);
          teBackupCerts->append(fileName);
      }
      
      void Backup::sltBackupCertsEnded(void)
      {
          cdThread->quit();
          cdThread->wait();
      }
      
      
      CopyData::CopyData() //QString srcDir, QString destDir)
      {
          qDebug() << "Constructor";
      }
      
      
      void CopyData::sltExecuteCopy(QString srcDir, QString destDir)
      {
          QDir sourceDirectory(srcDir);
          QDir destinationDirectory(destDir);
      
          uint32_t i = 0;
          foreach(QString directoryName, sourceDirectory.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
          {
              destinationDirectory.mkpath(destDir+"/"+directoryName);
              QString destinationPath = destDir+"/"+directoryName;
              destinationDirectory.mkpath(destinationPath);
      
              QDir currentSrcDir(srcDir + "/" + directoryName);
              qDebug() << currentSrcDir;
      
              foreach(QString fileName, currentSrcDir.entryList(QDir::Files))
              {
                  qDebug() << i << srcDir+"/"+directoryName+"/"+fileName << "--->" << destDir+"/"+directoryName+"/"+fileName;
                  QFile::copy(srcDir+"/"+directoryName+"/"+fileName, destDir+"/"+directoryName+"/"+fileName);
                  emit sigProgress(fileName, ++i);
              }
          }
      
      //    QDir finalDestination(destDir); //cantiere: gestire errori
      //    finalDestination.refresh();
      
          emit sigCopyEnded();
      }
      
      
      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Stefanoxjx said in Problem with QThread:

      QMetaObject::invokeMethod(cd, "sltExecuteCopy", Qt::DirectConnection,
                                    Q_ARG(QString, srcDir),
                                    Q_ARG(QString, destDir));
      

      What do you expect when you execute the function directly in the main thread?
      Where do you have this from? Please follow the official documentation and start the worker function with an appropriate signal (in the example it's a separate signal but QThread::started can be used here too).

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      3

      • Login

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