在函数内部的while循环中使用processEvents()

时间:2018-05-21 10:26:24

标签: c++ qt

我有一个插槽功能

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

此功能是从 QCheckBox 请求的功能,当按下复选框时,变量checked为真并进入while循环,当未按下复选框时,变量checkedfalse并从while循环中退出并进入if块,这是正常的,但我不知道理解的是,为什么在下一步中转到QcoreApplication::processEvents(),当它消失时,变量checked为真。

知道为什么会发生这些事情?

提前致谢!

1 个答案:

答案 0 :(得分:0)

你已经被重新进入事件循环的后果所困扰。现在你知道为什么这不是一个好主意。永远不要在主线程中阻塞,永远不要重新进入事件循环。反转控制流程以准确反映异步现实:

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