简体   繁体   English

等待SLOT完成

[英]Wait for a SLOT to finish

I use QNetworkAccessManager to do form POST. 我使用QNetworkAccessManager进行表单POST。

I have connected signals and slots as: 我已将信号和插槽连接为:

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

Now, I make a request by doing: 现在,我做了一个请求:

manager->post(request,postData);

Now readCookies(QNetworkReply *) will be run as soon as SIGNAL is emitted. 现在,只要发出SIGNAL,就会运行readCookies(QNetworkReply *)。 Now, using the Cookies which I get in this slot, I have to make one more POST.. 现在,使用我在这个插槽中获得的Cookies,我必须再制作一个POST ..

As signals & slots are asynchronous, I want to wait till I get the cookies from my first POST and then I again want to do another post using the cookies I got in first POST like 由于信号和插槽是异步的,我想等到我从第一次POST获取cookie然后我再次想要使用我在第一次POST中获得的cookie做另一篇文章

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

I want the later to always be executed after first one has executed (so that I get proper cookies value). 我希望后者总是在第一个执行后执行(这样我得到适当的cookie值)。

What is the way to go? 怎么走? I am new to all these SIGNALS & SLOTS so please bear with me. 我是所有这些信号和插槽的新手所以请耐心等待。

You can connect a signal from this to a slot from your manager and emit the signal after reading the cookies. 您可以将来自此信号的信号连接到管理器的插槽,并在读取cookie后发出信号。 By example: 举例:

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

So your readCookies function will be: 所以你的readCookies函数将是:

{
   // Read cookies
   emit cookiesRead();
}

Of course you can send all data you want form signal to slot. 当然,您可以将所需的所有数据发送到插槽。

Hope that helps 希望有所帮助

You can do the post in your readCookies() slot: 你可以在readCookies()插槽中发帖:

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

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

I will be called when the cookies is read, and you can then continue with your post. 我会在读取cookie时被调用,然后您可以继续发布您的帖子。 Connect that to a second slot, and so on. 将其连接到第二个插槽,依此类推。 Managing multiple, possibly parallely running asynchronous operations like this can become errorprone though, if you manage many of them in a single object. 如果你在一个对象中管理很多这样的异步操作,那么管理这样的多个,可能是并行运行的异步操作就会变成错误。 I would suggest to use the Command Pattern - here I described why I find it extremely useful in exactly this context. 我建议使用命令模式 - 在这里我描述了为什么我发现它在这个上下文中非常有用。 The sequence of request and asnychronous operations is encapsulated in a single object (abbreviated, with some pseudo-code): 请求和异步操作的顺序封装在单个对象中(缩写为一些伪代码):

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* );
};

To start the operation, you do 要开始操作,你可以

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
    }
}

It makes sense to have a common baseclass for such operations, see eg KDE's KJob . 为这样的操作设置一个共同的基类是有意义的,参见例如KDE的KJob

You can send a second signal connected to another slot (the resend slot), if you have finished the evaluation of your first cookie. 如果您已完成第一个cookie的评估,则可以发送连接到另一个插槽(重发插槽)的第二个信号。 You can do that directly in the slot. 您可以直接在插槽中执行此操作。 You can also call slots like a normal member function. 您也可以像普通成员函数一样调用插槽。

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

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