Solved Problems use QFtp in QThread
-
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. -
@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-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; } }
-
@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.