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
Forum Updated to NodeBB v4.3 + New Features

Problems use QFtp in QThread

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 231 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