Calling Component destroy with a Menu open crashes app on Mac only (even if Menu is dismissed explicitly)
-
Hi,
I recreated my issue on a sample app. I need to add several clickable components to a Rectangle, which all show Menu items on clicks. But some times, I need to remove everything from the UI.
-
If I "destroy" the component while one of the components inside the Rectangle has the menu popped visible, the app crashes <-- this itself is probably a bug
-
I fixed this on Windows by explicitly closing/dismissing the Menu before deleting the component. But it still crashes on Mac
-
Destroying the components separately didn't make any difference either.
Here are my two QML files:
main.qml
@import QtQuick 2.2
import QtQuick.Controls 1.1ApplicationWindow {
visible: true
width: 600
height: 600Rectangle { id: rootRectangle property Rectangle contentRectangle: null // this is the Rectangle which will have all the "ClickableRect.qml" components added dynamically property Menu lastMenuHandle: null // this will be set whenever the Menu with ClickableRect is invoked Button { id: button anchors.top: parent.top text: "Create Menu components" onClicked: { rootRectangle.addClickableRects(); } // onClicked } // Button Label { anchors.top : button.bottom text: "After creating the components, click one of them to pop up the menu, to recreate the crash.\nLeave the menu open for 5 seconds. App will try to remove the components from the UI" } Timer { id: uiClearTimer interval: 5000 // have to click the red component before this 5 seconds, just to create this edge case onTriggered: { console.log("uiClearTimer - onTriggered"); if (rootRectangle.contentRectangle !== null ) { if ( rootRectangle.lastMenuHandle !== null && rootRectangle.lastMenuHandle.__popupVisible ) { console.log ("Menu found open before destroying the component - closing it first"); rootRectangle.lastMenuHandle.__dismissMenu(); //rootRectangle.lastMenuHandle.__closeMenu(); // <-- close menu didn't make any difference } // NOTE: The following destroy calls go through (i.e prints out) but it crashes, if anyone of them had the menu opened var i = 0; var currChild; for (i=0; i<rootRectangle.contentRectangle.children.length; i++) { console.log("Destroying child component #" + i); currChild = rootRectangle.contentRectangle.children[i]; currChild.destroy(); } console.log("Destroying content rectangle"); // NOTE: Even if the containing rectangle isn't destroyed specifically, the child destroy calls are enough to crash the app rootRectangle.contentRectangle.destroy(); // <-- this function crashes the app on MAC only, if ONE of the ClickableRect component within it has the menu already opened. rootRectangle.contentRectangle = null; } } } function addClickableRects() { // first create the Rectangle if (rootRectangle.contentRectangle === null ) { rootRectangle.contentRectangle = Qt.createQmlObject("import QtQuick 2.0; Rectangle{anchors.fill: parent; color:\"yellow\"; border.width: 10 }", rootRectangle); if (rootRectangle.contentRectangle === null ) { console.log(" ERROR - couldn't create contentRectangle"); return; } // Now loop and add 5 "ClickableRect.qml" component to rootRectangle.contentRectangle var i; for (i=0; i<5; i++ ) { var clickableComp = Qt.createComponent("ClickableRect.qml"); if (clickableComp.status === Component.Ready) { var clickableObject = clickableComp.createObject(rootRectangle.contentRectangle, {"x":i*60, "y":100, "parentRect":rootRectangle}); } else { console.log(" ERROR - couldn't create object"); return; } // else } // for } else { console.log(" ERROR - components are already created"); } uiClearTimer.restart(); } // addComponents } // rootRectangle
}
@
ClickableRect.qml
@import QtQuick 2.0
import QtQuick.Controls 1.1Rectangle {
property Rectangle parentRect: null // this will be passed as an arg when component is being created. So that the menu handle be set properly // expose the menuHandle so that it can be closed from main.qml //property Menu menuHandle: functionMenu color: "red" width: 50 height: 50 border.width: 10 MouseArea { anchors.fill: parent onClicked: { // just pop open the menu functionMenu.popup(); } } Menu { id: functionMenu MenuItem { text: "Function 1" } on__PopupVisibleChanged: { if ( __popupVisible) { // update the handle to the tabView so that it is closed if the tabView removes these PaletteItem ui objects parentRect.lastMenuHandle = functionMenu; } } // on__popupVisibleChanged }
}
@The fact that workaround is fine on Windows but not on Mac, makes me guess that this is probably a bug. But I'm hoping that there is some sort of work around for the time being. Any feedback would be really helpful.
Thanks.
-