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. Problems use QFtp in QThread

Problems use QFtp in QThread

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 287 Views
  • 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.
  • Bruce.ZhangB Offline
    Bruce.ZhangB Offline
    Bruce.Zhang
    wrote on last edited by
    #1

    Hi Guys, I use QFtp in my project, now I faced a strange problem. The codes as follows:

    class FtpOutput: public QObject{
    private:
    QFtp* mQFtpPtr = nullptr;
    } 
    
    MyApp::MyApp(QObject *parent) : QObject(parent){
        mFtpThread = new QThread;
        mFtpOutput = new FtpOutput;
        mFtpOutput->setUrlStr("127.0.0.1");
        mFtpOutput->moveToThread(mFtpThread);
        connect(mFtpThread, &QThread::started, mFtpOutput, &FtpOutput::run);
        connect(mFtpThread, &QThread::destroyed, mFtpOutput, &FtpOutput::deleteLater);
        mFtpThread->start();
    }
    
    void FtpOutput::run()
    {
        static FileDescriptorPtr filePtr;
    
        if(mQFtpPtr == nullptr) {
            mQFtpPtr = new QFtp(this);
            //![1]
            this->connect(this, &FtpOutput::destroyed, mQFtpPtr, &QFtp::deleteLater);
    
            this->connect(mQFtpPtr, SIGNAL(commandFinished(int,bool)),
                          this, SLOT(onFtpCommandFinished(int,bool)));
            this->connect(mQFtpPtr, SIGNAL(dataTransferProgress(qint64,qint64)),
                          this, SLOT(onDataTransferProgress(qint64,qint64)));
            this->connect(mQFtpPtr, SIGNAL(stateChanged(int)),
                          this, SLOT(onStatusChange(int)));
            this->connect(mQFtpPtr, SIGNAL(listInfo(QUrlInfo)),
                          this, SLOT(onListInfo(QUrlInfo)));
            //![1]
        }
    
        QThread::msleep(100);
    
        int state = mQFtpPtr->state();
        //Step 1 check connection
        if(state == QFtp::Unconnected && mStep == 0) {
            doConnect();
            mStep = 1;
    }
    }
    

    The problem is when exec the doConnect(), nothing happens, but when I use QFtp directly from GUI( not use QThread), everything goes well.
    I tracked that:

    int QFtpPrivate::addCommand(QFtpCommand *cmd)
    {
        pending.append(cmd);
    
        if (pending.count() == 1) {
            // don't emit the commandStarted() signal before the ID is returned
            QTimer::singleShot(0, q_func(), SLOT(_q_startNextCommand()));
        } else {
            qDebug()<<"pending count:"<<pending.count();
        }
        return cmd->id;
    }
    

    When the code QTimer::singleShot exec,
    the _q_startNextCommand slot function not exec. Please help me.

    KroMignonK 1 Reply Last reply
    0
    • Bruce.ZhangB Bruce.Zhang

      Hi Guys, I use QFtp in my project, now I faced a strange problem. The codes as follows:

      class FtpOutput: public QObject{
      private:
      QFtp* mQFtpPtr = nullptr;
      } 
      
      MyApp::MyApp(QObject *parent) : QObject(parent){
          mFtpThread = new QThread;
          mFtpOutput = new FtpOutput;
          mFtpOutput->setUrlStr("127.0.0.1");
          mFtpOutput->moveToThread(mFtpThread);
          connect(mFtpThread, &QThread::started, mFtpOutput, &FtpOutput::run);
          connect(mFtpThread, &QThread::destroyed, mFtpOutput, &FtpOutput::deleteLater);
          mFtpThread->start();
      }
      
      void FtpOutput::run()
      {
          static FileDescriptorPtr filePtr;
      
          if(mQFtpPtr == nullptr) {
              mQFtpPtr = new QFtp(this);
              //![1]
              this->connect(this, &FtpOutput::destroyed, mQFtpPtr, &QFtp::deleteLater);
      
              this->connect(mQFtpPtr, SIGNAL(commandFinished(int,bool)),
                            this, SLOT(onFtpCommandFinished(int,bool)));
              this->connect(mQFtpPtr, SIGNAL(dataTransferProgress(qint64,qint64)),
                            this, SLOT(onDataTransferProgress(qint64,qint64)));
              this->connect(mQFtpPtr, SIGNAL(stateChanged(int)),
                            this, SLOT(onStatusChange(int)));
              this->connect(mQFtpPtr, SIGNAL(listInfo(QUrlInfo)),
                            this, SLOT(onListInfo(QUrlInfo)));
              //![1]
          }
      
          QThread::msleep(100);
      
          int state = mQFtpPtr->state();
          //Step 1 check connection
          if(state == QFtp::Unconnected && mStep == 0) {
              doConnect();
              mStep = 1;
      }
      }
      

      The problem is when exec the doConnect(), nothing happens, but when I use QFtp directly from GUI( not use QThread), everything goes well.
      I tracked that:

      int QFtpPrivate::addCommand(QFtpCommand *cmd)
      {
          pending.append(cmd);
      
          if (pending.count() == 1) {
              // don't emit the commandStarted() signal before the ID is returned
              QTimer::singleShot(0, q_func(), SLOT(_q_startNextCommand()));
          } else {
              qDebug()<<"pending count:"<<pending.count();
          }
          return cmd->id;
      }
      

      When the code QTimer::singleShot exec,
      the _q_startNextCommand slot function not exec. Please help me.

      KroMignonK Offline
      KroMignonK Offline
      KroMignon
      wrote on last edited by KroMignon
      #2

      @Bruce-Zhang Your code cannot work QThread::msleep(100); is an "active wait", so the QEventLoop of the thread is locked and all signals are not executed!

      I would also recommend you to use new connect syntax to allow signals/slots validity check at compilation.

      void FtpOutput::run()
      {
          if(mQFtpPtr == nullptr) {
              mQFtpPtr = new QFtp(this);
      		// => not needed, because this is parent
              //connect(this, &FtpOutput::destroyed, mQFtpPtr, &QFtp::deleteLater);
              connect(mQFtpPtr, &QFtp::commandFinished, this, &FtpOutput::onFtpCommandFinished);
              connect(mQFtpPtr, &QFtp::dataTransferProgress, this, &FtpOutput::onDataTransferProgress);
              connect(mQFtpPtr, &QFtp::stateChanged, this, &FtpOutput::onStatusChange);
              connect(mQFtpPtr, &QFtp::listInfo, this, &FtpOutput::onListInfo);
      
      		//Step 1 start connection
              doConnect();
              mStep = 1;
          }
      }
      

      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

      Bruce.ZhangB 1 Reply Last reply
      4
      • KroMignonK KroMignon

        @Bruce-Zhang Your code cannot work QThread::msleep(100); is an "active wait", so the QEventLoop of the thread is locked and all signals are not executed!

        I would also recommend you to use new connect syntax to allow signals/slots validity check at compilation.

        void FtpOutput::run()
        {
            if(mQFtpPtr == nullptr) {
                mQFtpPtr = new QFtp(this);
        		// => not needed, because this is parent
                //connect(this, &FtpOutput::destroyed, mQFtpPtr, &QFtp::deleteLater);
                connect(mQFtpPtr, &QFtp::commandFinished, this, &FtpOutput::onFtpCommandFinished);
                connect(mQFtpPtr, &QFtp::dataTransferProgress, this, &FtpOutput::onDataTransferProgress);
                connect(mQFtpPtr, &QFtp::stateChanged, this, &FtpOutput::onStatusChange);
                connect(mQFtpPtr, &QFtp::listInfo, this, &FtpOutput::onListInfo);
        
        		//Step 1 start connection
                doConnect();
                mStep = 1;
            }
        }
        
        Bruce.ZhangB Offline
        Bruce.ZhangB Offline
        Bruce.Zhang
        wrote on last edited by
        #3

        @KroMignon said in Problems use QFtp in QThread:

        connect(mQFtpPtr, &QFtp::commandFinished, this, &FtpOutput::onFtpCommandFinished);
        connect(mQFtpPtr, &QFtp::dataTransferProgress, this, &FtpOutput::onDataTransferProgress);
        connect(mQFtpPtr, &QFtp::stateChanged, this, &FtpOutput::onStatusChange);
        connect(mQFtpPtr, &QFtp::listInfo, this, &FtpOutput::onListInfo);

        Thanks a lot, really works.

        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