Как мне остановить и запустить цикл в QT?

#c #qt

#c #qt

Вопрос:

Я пытался выяснить, как заставить программу остановиться в цикле for и дождаться нажатия кнопки, после чего цикл for продолжится.

Нет ли какого-нибудь простого способа остановить цикл, например, QSystem.stop() и в функции нажатия кнопки QSystem.star() , и цикл продолжается.

В C вы могли бы использовать system("pause") или программа остановилась, когда вы использовали cin<< . Но как мне сделать это в QT?

Комментарии:

1. Тому, кто голосует за снижение. Это хороший вопрос. OP не разобрался в семантике программирования на основе событий. Совершенно правильный вопрос, который нужно задать.

2. На всякий случай: вы знаете, что такое отладчик? Вы знаете, как это использовать?

Ответ №1:

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

Что вы можете сделать, так это создать второй поток и дождаться переменной условия. Поток GUI может сигнализировать об этой переменной условия в слоте события нажатия кнопки.

В C вы могли бы использовать system («пауза») или программа остановилась

Точно: программа остановлена. Это означает, что он не будет извлекать события из операционной системы. Однако получение данных из stdin не является событием. Это блокирует потоковый ввод-вывод. Хотя графические пользовательские интерфейсы основаны на событиях.

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

Комментарии:

1. Спасибо datenwolf, это очень помогло мне 🙂

Ответ №2:

Вам не нужны потоки, вложенный цикл событий выполнит эту работу.

 int waitUntilSignalIsEmitted(QObject *sender, const char *signal) {
    QEventLoop loop;
    connect(sender, signal,
            amp;loop, SLOT(quit()));
    return loop.exec();
}

// usage:
while(yourLoopCondition) {
   // some stuff
   ...
   // pause here
   waitUntilSignalIsEmitted(yourContinuationButton, SIGNAL(clicked()));

   // loop continuation
   ...
}
  

Комментарии:

1. Конечно, вложенный цикл событий — это зло, которого лучше избегать, поскольку оно приводит к ошибкам, которые бывает очень трудно выявить. Однако ваш код является отличным примером, который находит применение при переносе из других наборов инструментов в Qt.

2. У меня никогда не было проблем с этим, но я никогда не злоупотреблял этим. В любом случае, для новичка намного лучше и безопаснее играть с потоками.

3. Я думаю, что с педагогической точки зрения новичку действительно следует изучить асинхронное кодирование и как использовать таймеры нулевой длины. Тогда проблема с потоком не является проблемой: можно переместить объект в новый поток, если / когда это удобно.

4. Скорее всего, вы правы. Я почти уверен, что он неправильно задал вопрос. Я имею в виду, что у него есть какая-то простая проблема, которую он пытается решить таким странным способом, поэтому он просит нас исправить его решение, вместо этого объясняя реальную проблему. Я не удивлюсь, если debugger — это то, что ему действительно нужно.