我正在开发一个将文件内容上传到服务器的应用程序。
要将文件上传到服务器,我使用的是“QNetworkAccessManager”类。由于它以异步方式工作,我通过使用QEventLoop将其更改为以同步方式工作。
Class FileTransfer
{
Public :
QNetworkAccessManager mNetworkManager;
Void Upload(QNetworkRequest request, QIODevice *data)
{
responce = mNetworkManager.put(request, data);
EventLoop.exec();
ReadResponce(responce);
}
Void Stop()
{
responce ->close();
}
}
在我的示例应用程序中,我有2个窗口。第一个选择文件,第二个显示进度。
当用户点击第一个窗口中的上传按钮时,将显示第二个窗口,然后我创建 FileTransfer 对象并开始上传。
在用户关闭表单时上传文件,然后在窗口的析构函数中,我调用“ FileTransfer ”的句号,然后删除“ FileTransfer ”对象
但是 Upload()功能尚未完成,因此会崩溃。
请帮助我: 如何在'stop()'函数中等待,直到Upload()函数完成
答案 0 :(得分:19)
从我的代码中可以看出,你正在执行一个QEventLoop,但实际上并没有将它的“退出”插槽连接到任何信号。以下面的例子为例,login是一个QHttp - 代码取自不同的东西 - 但原则适用。
/* Create the QEventLoop */
QEventLoop pause;
/* connect the QHttp.requestFinished() Signal to the QEventLoop.quit() Slot */
connect(&login, SIGNAL(requestFinished( int, bool )), &pause, SLOT(quit()));
/* The code that will run during the QEventLoop */
login.request(header,&logmein,&result);
/* Execute the QEventLoop - it will quit when the above finished due to the connect() */
pause.exec();
这可以应用于你的代码,如果我没有弄错的话,就像这样......
/* connect the signal to the relevant slot */
connect(&mNetworkManager, SIGNAL(finished( QNetworkReply )), &EventLoop, SLOT(quit()));
/* Execute the code that will run during QEventLoop */
responce = mNetworkManager.put(request, data);
/* Execute the QEventLoop */
EventLoop.exec();
如果我误解了您的查询,请道歉!我只是在休息后再次掌握qt,但我相信这就是你的意思!祝你好运!
答案 1 :(得分:0)
我认为您需要在上传功能中添加类似内容:
if (upf->openFile())
{
reply = manager->post(request, upf);
connect(reply, SIGNAL(uploadProgress(qint64,qint64)), this, SIGNAL(progress(qint64,qint64)));
connect(reply, SIGNAL(finished()), this, SLOT(replyFinished()));
isInProgress = true;
emit started();
} else
{
emit finished(true, false, tr("Error: can't open file %1").arg(filename));
}
以下是全文代码:datacod-qt-tools
希望有所帮助。
答案 2 :(得分:0)
就个人而言,我建议不要使用任何这些答案。 将倒计时锁存器连接到信号就足够了。
所以你可以写:
Latch latch( 1 );
QObject::connect( reply, SIGNAL(finished()),
&latch, SLOT(countDown()) );
latch.wait();
为此你需要一个包装器:
class Latch : public QObject {
Q_OBJECT
public:
Latch( uint count );
void wait();
public slots:
void countDown();
private:
gcl::countdown_latch _latch;
};