等待SLOT完成

时间:2010-12-23 12:17:01

标签: c++ qt qt4 signals-slots

我使用QNetworkAccessManager进行表单POST。

我已将信号和插槽连接为:

connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(readCookies(QNetworkReply*)));

现在,我做了一个请求:

manager->post(request,postData);

现在,只要发出SIGNAL,就会运行readCookies(QNetworkReply *)。现在,使用我在这个插槽中获得的Cookies,我还要再做一次POST ..

作为信号&插槽是异步的,我想等到我从第一次POST获取cookie然后我再次想要使用我在第一次POST中获得的cookie做另一篇文章

//Setting new request, headers etc...
manager->post(request2,postData2);

我希望后者在第一个执行后始终执行(以便我获得正确的cookie值)。

要走的路是什么?我是所有这些信号的新手。 SLOTS所以请耐心等待。

3 个答案:

答案 0 :(得分:4)

您可以将来自此信号的信号连接到经理的插槽,并在读取Cookie后发出信号。例如:

connect(this, SIGNAL(cookiesRead()), manager, SLOT(PostAgain());

所以你的readCookies函数将是:

{
   // Read cookies
   emit cookiesRead();
}

当然,您可以将所需的所有数据发送到插槽。

希望有所帮助

答案 1 :(得分:4)

您可以在readCookies()广告位中填写帖子:

void readCookies( QNetworkReply* reply ) {
    if ( ...error? ) {
        report error...
        return;
    }

    ...
    manager->post(request2,postData2);
}

读取cookie后我会被调用,然后您可以继续发布。将其连接到第二个插槽,依此类推。 如果你在一个对象中管理很多这样的异步操作,那么管理这样的多个,可能是并行运行的异步操作就会变成错误。我建议使用命令模式 - here I described 为什么我发现它在这种情况下非常有用。请求和异步操作的顺序封装在一个对象中(缩写为一些伪代码):

class PostStuffOperation : public QObject {
    Q_OBJECT
public:
    enum Error {
       NoError=0,
       Error=1,
       ...
    };

    Error error() const; //operation successful or not?
    QString errorString() const; //human-readable error description

    ... setters for all the information the operation needs
    ...
    void start() {
       ...start your first request and connect it to cookiesRead 
    }

public Q_SLOTS:
    void cookiesRead( QNetworkReply * ) {
    if ( error ) {
       // set error and errorString...
       emit finished( this ); //couldn't read cookies, so the operation fails
       return;
    }
    ... do post
 }

 void postFinished( QNetworkReply* ) {
     if ( error ) {
         // set error and errorString...
     }

    emit finished( this ); //post finished - that means the whole operation finished
 }
Q_SIGNALS:
    void finished( PostStuffOperation* );
};

要开始操作,请执行

PostStuffOperation op* = new PostStuffOperation( this );
... pass data like server, port etc. to the operation
connect( op, SIGNAL(finished()), this, SLOT(postOperationFinished()) );
op->start();

void postOperationFinished( PostStuffOperation* op ) {
    if ( op->error != PostStuffOperation::NoError ) {
        //handle error, e.g. show message box
    }
}

为此类操作设置公共基类是有意义的,例如, KDE的KJob

答案 2 :(得分:0)

如果您已完成对第一个Cookie的评估,则可以发送连接到另一个插槽(重发插槽)的第二个信号。您可以直接在插槽中执行此操作。您也可以像普通成员函数一样调用插槽。

相关问题