Использование processEvents () в цикле while внутри функции - PullRequest
0 голосов
/ 21 мая 2018

У меня есть функция слота

    void MobilePlatform::slot_lineFollow(bool checked) 
    {
        while(checked){
            ...
            QCoreApplication::processEvents(); 
        }
        if(!checked){
            ....
        }
    }

Эта функция запрашивается у QCheckBox , а когда флажок нажата переменная checked имеют значение true и переходят в цикл while, а когда флажок не нажат, переменная checked равна false, выходит из цикла while и переходит в блок if, это нормально,но я не понимаю, почему на следующем шаге переходит к QcoreApplication::processEvents(), а когда он выходит, переменная checked имеет значение true.

Кто-нибудь знает, почему это происходит?

Заранее спасибо!

1 Ответ

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

Вы получили укусы от повторного входа в цикл событий.Теперь вы знаете, почему это не очень хорошая идея.Никогда не блокируйте в главном потоке и никогда не перезапускайте цикл событий.Инвертировать поток управления для точного отражения асинхронной реальности:

class MobilePlatform : public QWidget {
  Q_OBJECT
  using self = MobilePlatform;
  using base_class = QWidget;
  using spin_handler = void (self::*)();
  QBasicTimer m_spinTimer;
  ...

  Q_SIGNAL void spinSignal();
  void spin(spin_handler);
  void despin(spin_handler);
  void follower();
  Q_SLOT void slot_lineFollow(bool checked);
protected:
  void timerEvent(QTimerEvent *) override;
public:
  ...
};

void MobilePlatform::timerEvent(QTimerEvent *ev) {
  if (ev->timerId() == m_spinTimer.timerId())
    Q_EMIT spinSignal();
  else
    base_class::timerEvent(ev);
}

void MobilePlatform::spin(spin_handler handler) {
  if (!m_spinTimer.isActive())
    m_spinTimer.start(0, this);
  connect(this, &self::spinSignal, this, handler, Qt::UniqueConnection | Qt::DirectConnection);
  Q_ASSERT(m_spinTimer.isActive());
}

void MobilePlatform::despin(spin_handler handler) {
  static const auto signal = QMetaMethod::fromSignal(&self::spinSignal);
  Q_ASSERT(signal.isValid());
  disconnect(this, &self::spinSignal, this, handler);
  auto const hasHandlers = isSignalConnected(signal);
  if (!hasHandlers)
    m_spinTimer.stop();
  Q_ASSERT(m_spinTimer.isActive() == hasHandlers);
}

void MobilePlatform::follower() {
  /* code that runs when following */
  ...
}

void MobilePlatform::slot_lineFollow(bool checked) {
  if (checked()) {
    spin(&self::follower);
  } else {
    despin(&self::follower);
    ...
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...