我正在开发一个 Qt (5.3) 桌面应用程序(带有 QML ui 的 C++ 核心),其主窗口是 anApplicationWindow
并且在某些时候会启动Dialog
s。由于 Windows 和 Mac OS X 之间对话模式的使用存在差异(例如,关于对话框在 Mac OS X 上很少是模态的,但在 Windows 上几乎总是模态的)以及呈现某些对话框内容的方式,我已经更改了设计以允许实现特定于平台的对话框版本。
为此,我创建了以下DialogLoader:
Loader {
id: dialogFactory
property string dialogName
function platformFolder() {
if (Qt.platform.os === "osx")
return "osx"
return "win"
}
onDialogNameChanged: { source = platformFolder() + "/" + dialogName + ".qml" }
onStatusChanged: {
if (dialogFactory.status === Loader.Error)
console.log("DialogFactory: failed to load file: " + source);
else if (dialogFactory.status === Loader.Ready)
console.log("DialogFactory: file \"" + source + "\" loaded")
}
}
我使用如下:
ApplicationWindow {
// …
property alias aboutDialog: aboutDialogLoader.item
// …
DialogLoader { id: aboutDialogLoader; dialogName: "AboutDialog" }
// …
Action { text: qsTr("About..."); onTriggered: aboutDialog.show() }
// …
}
这种方法运行良好,它符合我的需要,除了一件事:Windows 上的模态对话框的行为与我直接声明它们时的行为不同ApplicationWindow
。如果在打开模式窗口并再次授予焦点时应用程序失去焦点,则模式窗口会出现在主窗口后面,这会导致应用程序无法运行。
经过一些研究,我意识到问题的原因是使用加载器方法时,ApplicationWindow
它没有充当Dialog
.
我找到了一种解决方法,方法是在发生这种情况时手动将对话框置于前面:
MainWindow {
// ...
onActiveChanged: {
if (Qt.platform.os === "windows") {
if (active) {
// ...
if (aboutDialog.visible) {
aboutDialog.requestActivate()
}
// ...
}
}
}
// ...
}
但我认为如果可能的话,最好避免这种变通办法。在没有任何运气的情况下深入研究 Qt 文档后,我决定发布这个问题,可以恢复如下:Is it possible to change the transient parent of a QML Window?如果是这样,请你指出如何?
欢迎提出有关可以避免重复内容的不同方法的建议。