Как работает локальный QEventLoop - PullRequest
0 голосов
/ 21 мая 2018

Мой вопрос носит общий характер и связан с использованием класса QEventLoop в QT.У меня есть два основных вопроса по этому поводу.

вопрос 1) как это работает внутри QT (моя главная задача - почему выполнение объекта QEventLoop не блокируетсяосновной цикл приложения QT - [EDIT 3], этот последний комментарий не соответствует действительности, см. ответы ниже ).Подробности см. Ниже.

вопрос 2) Есть ли у него иная цель, кроме блокировки?Кажется, я могу встретить только примеры, когда QEventLoop используется для цели ожидания.Можно ли его использовать для других целей?Как мы могли бы представить себе передачу определенных событий из основного цикла приложения в локальный цикл QEventLoop?(не уверен, что этот вопрос имеет какой-либо смысл)

Развитие вопроса 1):

Мое понимание того, как в основном работает цикл главных событий QT, заключается в следующем.Основной цикл событий приложения ( QCoreApplication :: exec () ) извлекает QEvent"E" из очереди и отправляет его QObject"A"он решает, что событие должно перейти (например, позиция и Z-значение QWidget в случае нажатия левой кнопкой мыши).Если мы предположим, что объект «A» использует событие «E», вызывается метод события этого объекта (есть другие удобные методы и фильтры событий, но давайте предположим, что метод события имеет дело с событием в нашем случае) - некоторая обработкасвязанный с объектом «А» происходит здесь - и возвращает истину.Затем основной цикл событий QT начинает обработку следующего события в очереди и т. Д.

Однако IF что-то блокирует при вызове метода события объекта "«Я бы ожидал, что основной цикл приложения будет заблокирован, поскольку он ожидает возврата метода события получателя (объект« А ») ...Так, например, если обработка события завершается вызовом метода объекта «A», в котором мы создаем локальный QEventLoop , который мы никогда не завершаем, я ожидаю, что все приложение будет остановлено и не болеесобытия обрабатываются до тех пор, пока локальный QEventLoop не будет завершен, и метод события объекта "A" не вернется.В противном случае это не так, поскольку я мог видеть, что локальный QEventLoop не блокирует основной цикл обработки событий приложения ...Может кто-нибудь дать мне больше информации о том, как работает локальный QEventLoop ? [РЕДАКТИРОВАТЬ 3] см. Ответ ниже, локальный цикл обработки событий обрабатывает события

---- РЕДАКТИРОВАТЬ 1 ----

Извините, если мне не ясно, это на самом деле довольно сложно объяснить словами, поэтому ниже приведеннебольшой фрагмент кода, чтобы лучше проиллюстрировать мой вопрос 1 .

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include <QPushButton>
#include <QEventLoop>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    QPushButton* button1 = new QPushButton(this);
    button1->setText("button 1");
    button1->setCheckable(true);

    QPushButton* button2 = new QPushButton(this);
    button2->setText("button 2");
    button2->move(0,50);

    connect(button1,&QPushButton::toggled,button1,[button1](bool toggled){
        button1->setText(toggled ? "CHECKED" : "NOT CHECKED");
    });

    connect(button2,&QPushButton::clicked,button2,[](){
        QEventLoop loop;
        qInfo() << "Before loop exec";
        loop.exec();
        qInfo() << "After loop exec";
    });
}

MainWindow::~MainWindow()
{
}

main.cpp

#include "mainwindow.h"
#include <QApplication>

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();

        return a.exec();
    }

В приведенном выше примере у меня есть простое окно с 2 кнопками «кнопка 1» (которое отображает его состояние:проверено или не проверено) и «кнопка 2» (которая запускает локальный QEventLoop при нажатии).Когда я нажимаю на кнопку 2, она блокируется в «loop.exec ()», то есть второе сообщение отладки никогда не выводится.Затем я ожидал бы, что основной цикл приложения также будет заблокирован, однако я не думаю, что это так, поскольку я все еще могу нажать «кнопку 1», которая отображает ее состояние (отмечено или не отмечено), то есть события мышивсе еще обрабатывается основным циклом событий приложения.

1 Ответ

0 голосов
/ 21 мая 2018

Нет, события не обрабатываются основным циклом событий QApplication.Они обрабатываются loop и отправляются на свои обычные места.

Код, который вы представили, не имеет возможности завершить loop.Ничто не мешает вам снова нажать button2 и иметь еще один loop в двух запущенных в данный момент (первый loop и основной цикл QApplication).

Если вы присоединяете отладчик к своему процессу, вы увидите кадр стека для каждого цикла, который выполняется

...