繁体   English   中英

等待SLOT完成

[英]Wait for a SLOT to finish

我使用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值)。

怎么走? 我是所有这些信号和插槽的新手所以请耐心等待。

您可以将来自此信号的信号连接到管理器的插槽,并在读取cookie后发出信号。 举例:

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

所以你的readCookies函数将是:

{
   // Read cookies
   emit cookiesRead();
}

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

希望有所帮助

你可以在readCookies()插槽中发帖:

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM