从QItemDelegate的自定义编辑器调用getOpenFileName时发生崩溃

先决条件:

我有一个自定义的QItemDelegate,它为treeview项目创build自定义编辑器。 编辑器由QLineEdit和QToolButton组成。 该button用于打开文件对话框以select文件并将其path放入行编辑。 我使用QFileDialog :: getOpenFileName调用来打开文件对话框。 该对话框是本地Windows文件对话框(这很重要)。

编辑器第一次创build时,无论按多less次button,一切都正常。 但是在编辑器closures并重新打开之后,首先按下button会导致崩溃。 崩溃的原因是我的自定义编辑器最终被删除。

这里是一些代码:

void CCustomEditor::on_RunSetupBtn_clicked() { auto qFilename = QFileDialog::getOpenFileName(this, "Select application to run", QString(), "Executable files (*.exe)"); if (qFilename.isEmpty()) return; SetCommandLine(QDir::toNativeSeparators(qFilename), m_qParameters); } 

Solutions Collecting From Web of "从QItemDelegate的自定义编辑器调用getOpenFileName时发生崩溃"

我做了一些挖掘,发现调用WinAPI函数GetOpenFileName结果的方式是一样的:我的编辑器被删除(尽管崩溃不会发生)。 Qt似乎也在内部调用它。

我追踪了为什么我的编辑器被删除的原因,并发现当getOpenFileName被调用时,活动窗口改变和焦点的变化。 在第一种情况下,焦点从TreeView项移动,但在第二种情况下,它从编辑器本身移动! 这会导致编辑器因“聚焦”事件而被删除。

重要的是要说,如果创建文件对话框时设置了“DontUseNativeDialog”标志,则不会发生这种情况。 因此,这应该是Qt窗口管理本地窗口和Qt窗口小部件之间的一个错误。

作为这个错误的解决方法,我建议以下解决方案:在调用getOpenFileName之前,将焦点设置为按钮本身。

  m_pUI->RunSetupBtn->setFocus(); auto qFilename = QFileDialog::getOpenFileName(this, "Select application to run", QString(), "Executable files (*.exe)"); 

另一个解决方法是使用'DontUseNativeDialog'标志,但是生成的文件对话框看起来不是本地的,实际上它非常难看。 如果有人有更好的解决方案,随时分享。