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.
1) 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
2) I fixed this on Windows by explicitly closing/dismissing the Menu before deleting the component. But it still crashes on Mac
3) 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.1
ApplicationWindow {
visible: true
width: 600
height: 600
Rectangle {
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.1
Rectangle {
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.
↧