Подождите, пока слот закончится - PullRequest
4 голосов
/ 23 декабря 2010

Я использую QNetworkAccessManager для создания формы POST.

Я подключил сигналы и слоты как:

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

Теперь я делаю запрос, выполнив:

manager->post(request,postData);

Теперь readCookies (QNetworkReply *) будет запущен, как только появится сигнал SIGNAL. Теперь, используя Cookies, которые я получаю в этом слоте, я должен сделать еще один POST ..

Поскольку сигналы и слоты асинхронны, я хочу подождать, пока я получу куки с моего первого POST, а затем снова хочу сделать еще одну запись, используя куки, которые я получил в первом POST, например

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

Я хочу, чтобы последующие всегда выполнялись после первого выполнения (чтобы получить правильное значение cookie).

Какой путь? Я новичок во всех этих сигналах и слотах, поэтому, пожалуйста, потерпите меня.

Ответы [ 3 ]

4 голосов
/ 23 декабря 2010

Вы можете сделать сообщение в своем слоте 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 .

4 голосов
/ 23 декабря 2010

Вы можете подключить сигнал от этого к слоту от вашего менеджера и испустить сигнал после чтения куки.Например:

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

Таким образом, ваша функция readCookies будет:

{
   // Read cookies
   emit cookiesRead();
}

Конечно, вы можете отправлять все данные, которые вы хотите сформировать, в слот.помогает

0 голосов
/ 23 декабря 2010

Вы можете отправить второй сигнал, подключенный к другому слоту (слоту для повторной отправки), если вы завершили оценку вашего первого файла cookie.Вы можете сделать это прямо в слоте.Вы также можете вызывать слоты как обычные функции-члены.

...