11

我正在开发一个将文件内容上传到服务器的应用程序。

要将文件上传到服务器,我正在使用“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对象并开始上传。

如果用户关闭表单,则在上传文件时,然后在窗口的析构函数中调用“<em>FileTransfer”的停止,然后删除“<em>FileTransfer”对象。

但是这里的Upload()函数还没有完成,所以它会崩溃。

请帮我:如何在“stop() ”函数中等待,直到 Upload() 函数完成

4

3 回答 3

19

从我从您的代码中可以看出,您正在执行 QEventLoop 但实际上并未将其“退出”插槽连接到任何信号。以下面为例,登录是一个 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,但我相信这就是你的意思!祝你好运!

于 2010-06-16T10:37:17.180 回答
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

希望它有所帮助。

于 2010-06-16T10:13:35.463 回答
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;
};
于 2013-06-28T13:28:19.630 回答