在我的代码上下文中,纯JavaScript库(标记为".pragma库“)中的函数与QML中的成员函数之间有什么区别?
import QtQuick 2.15
import QtQuick.Controls 2.15
import "."
ApplicationWindow {
id: applicationWindow
width: 400
height: 400
visible: true
function showDialog(params) {
const comp = Qt.createComponent("qrc:/MyPopup.qml");
const err = comp.errorString();
if (err)
console.log("MyPopup component loading failed:", err);
const dlg = comp.createObject(params.parent, params);
console.assert(dlg !== null, "MyPopup object creation failed");
console.log("opening");
dlg.open();
}
Button {
text: "Press me"
anchors.centerIn: parent
onClicked: {
console.log("you press button");
const params = {parent: applicationWindow.contentItem};
//applicationWindow.showDialog(params); // !!! 1
CreateDialog.showDialog2(params); // !!! 2
}
}
}我的弹出式窗口:
import QtQuick 2.0
import QtQuick.Controls 2.15
Popup {
id: view
width: 300
height: 300
onClosed: {
console.log("onClosed was called", view);
view.destroy();
}
Text {
anchors.centerIn: parent
text: "Popup!!!"
}
}如果我使用变体(1),如果我打开弹出,然后按"Alt+F4“(在macOS上)或"Command+Q”,所有操作都很好。
但是,如果我将“showDialog”移到“CreateDialog.js”文件中,并在其顶部添加“.pragma库”,那么在使用打开的弹出式退出应用程序时,我会得到:
qrc:/MyPopup.qml:11: TypeError: Cannot call method 'destroy' of null因此Qt/QML运行时调用死对象的信号。究竟是怎么回事,在“纯javascript”的情况下引用对话框“悬挂”,所以Qt不能正确地销毁它?
发布于 2021-04-12 23:46:14
默认情况下,从QML导入的JavaScript文件与QML组件共享它们的上下文。 --如果从JS文件中删除.pragma library,代码的行为与在主QML文件中运行JS代码的行为相同,因为它们共享相同的上下文。那么,为什么.pragma library会影响到这一点呢?.pragma library创建了一个类似于单例的JS文件,而且由于任何QML文件都可以访问它,所以它的上下文通常被设置为根上下文或一些顶级的孤立上下文(不确定,无法从文档中确定),而不是调用它的文件的上下文。
根据背景文件:
虽然在上下文中实例化的QML对象并不严格属于该上下文,但它们的绑定是。如果上下文被销毁,未决QML对象的属性绑定将停止计算。
我相信你所看到的与第二句相反,在第二句中,根上下文拥有弹出窗口的绑定,并且在它被破坏后调用它的onClosed信号。
因此,您的两个场景描述了:
第一个场景:
applicationWindow父级的弹出窗口,其创建上下文与applicationWindow匹配applicationWindow销毁开始applicationWindow的子程序,所以它被销毁了。applicationWindow上下文被破坏,绑定将停止计算。第二个场景:
applicationWindow父级,但其创建上下文是根上下文applicationWindow销毁开始applicationWindow的子程序,所以它被销毁了。applicationWindow上下文被销毁applicationWindow销毁后,将调用弹出关闭信号,因为其(根)创建上下文仍然存在,而由于信号处理程序中的引用已被销毁,引发错误。解决这一问题的最好方法可能是在管理对象创建的JS文件中不使用.pramga library。否则,它并不是一个特别令人担忧的错误,因为它足够聪明地知道引用已经被销毁,并且没有访问已释放的内存。您可以通过在调用if (view)之前检查view.destroy()来消除错误
https://stackoverflow.com/questions/67065636
复制相似问题