我的应用程序在使用QFileDialog::getExistingDirectory时停止通过QSerialPort接收数据。对话框关闭后,它将继续接收数据。有办法防止这种情况吗?

最佳答案

您正在调用阻塞方法。执行该方法时,事件循环无法运行,因为它位于调用堆栈底部的某个位置,等待您的插槽返回它。由于世界是异步的,所以这是同步的编码方式,无法反射(reflect)实际情况。所以不要这样编码。

相反,您应该在文件对话框不可见时进行设置,然后对其进行show()编码,并在连接至QDialog::accepted()信号的插槽中执行所需的代码。

您可以考虑设置,并拥有一个不错的异步帮助器,类似于getExistingDirectory:

template <typename F> void withExistingDirectoryDo(F && fun, QObject * context = 0,
  QWidget * parent = 0, const QString & caption = QString(),
  const QString & dir = QString(), Options options = QFileDialog::ShowDirsOnly) {
  auto * dialog = new QFileDialog(parent);
  auto helper = [fun, dialog]{ fun(dialog->directory()); };
  if (context)
    connect(dialog, &QDialog::accepted, context, helper);
  else
    connect(dialog, &QDialog::accepted, helper);
  dialog->setAttribute(Qt::WA_DeleteOnClose);
  dialog->setOptions(options);
  dialog->setFileMode(QFileDialog::Directory);
  dialog->show();
}

这是代码转换:
void before() {
  foo();
  auto dir = QFileDialog::getExistingDirectory(); // bad synchronous code
  bar(dir);
}

void after() {
  foo();
  withExistingDirectoryDo([this](const QDir & dir) {
    bar(dir);
  }, this);
}

10-08 03:37