同步Window.show()

时间:2016-02-09 02:43:02

标签: javascript qt qml

在我的项目中,我使用从Window派生的自定义组件来显示消息。目前我使用此代码:

function showMessage(title, text) {
    var component = Qt.createComponent("MessageBox.qml");
    if (component.status === Component.Ready) {
        var dialog = component.createObject(parent);
        dialog.caption = title;
        dialog.message = text;
        dialog.show();
        return dialog;
    }
}

但现在我想在JS中使用它作为confirm(),即现在应该等到用户点击对话框中的相应按钮,然后返回值(true / false)。

一种理想的用法是验证用户表单,例如:

function checkAForm() {
    if(!showMessage("Warning","The field f1 is empty. Do you want to continue?"))
        return false;
    if(!showMessage("Warning","Some warning"))
        return false;
    if(!showMessage("Warning","Some another warning"))
        return false;
    return true;
}

现在此功能总是同时显示3个窗口并返回false

第一个想法是通过信号连接实现它:

function checkAForm() {
    var dialog1 = showMessage("...","...");
    dialog1.accepted.connect(function(){
        var dialog2 = showMessage("...","...");
        dialog2.accepted.connect(function(){
            var dialog3 = showMessage("...","...");
            dialog3.accepted.connect(function(){
                return true;
            });
        });
    });
}

其中accepted是用户点击MessageBox.qml按钮时发出Ok的信号。

但这种结构太复杂而且不太清楚。如果使用点击Cancel,我也不知道该怎么办。

所以现在我正在寻找一个好主意如何实现Window.show()的同步调用,或者可能是其他一些想法,也许是一些信号量或类似的东西。

1 个答案:

答案 0 :(得分:3)

据我迄今为止的评论所理解,似乎同步性/异步性(阻止或不阻止GUI线程)可能不是这里的问题,但是你想要在一个序列中有多个对话框窗口,在我看来有点像巫师。

为此目的,使用您当前的方法,为什么不这样做:

首先,您可以将自定义MessageBox.qml设置为:

Item {
...
    property var acceptedFunction
    property var canceledFunction
...
    Button {
        id: acceptedButton
        onClicked: { acceptedFunction() }
    }
    Button {
        id: canceledButton
        onClicked: { canceledFunction() }
    }
...
}

然后,在利用qml:

    function startTheShow() {
        showFirstWindow()
    }

    function showFirstWindow() {
        var title = "First Window's Title"
        var text = "First Window's Text"
        var component = Qt.createComponent("MessageBox.qml");
        if (component.status === Component.Ready) {
            var dialog = component.createObject(parent);
            dialog.caption = title;
            dialog.message = text;
            dialog.acceptedFunction = showSecondWindow
            dialog.canceledFunction = function() { ...do something here... } //This is just for an example how you can have it also -- as an anonymous function.
            dialog.show();
        }
    }

    function showSecondWindow() {
        var title = "Second Window's Title"
        var text = "Second Window's Text"
        var component = Qt.createComponent("MessageBox.qml");
        if (component.status === Component.Ready) {
            var dialog = component.createObject(parent);
            dialog.caption = title;
            dialog.message = text;
            dialog.acceptedFunction = showThirdWindow
            dialog.canceledFunction = function() { ...do something here... } //This is just for an example how you can have it also -- as an anonymous function.
            dialog.show();
        }

    function showThirdWindow() ...and so on

如果您使用上述内容,您可能也可以使用一个常规函数和一组对象作为窗口流的配置。也许是这样的事情:

MessageBox.qml:

Item {
...
    property int myIndex
    property var showNextWindowFunc
    Button {
        id: acceptedButton
        onClicked: { showNextWindowFunc(myIndex+1) }
    }
    Button {
        id: canceledButton
        onClicked: { ...do some standard thing perhaps?... }
    }
...
}

utilizingQml.qml:

property var myWindowSequenceConfiguration: [
    { "title" : "Title 1", "text" : "Text 1" },
    { "title" : "Title 2", "text" : "Text 2" },
    ...
]

function showWindow(index) {
    var component = Qt.createComponent("MessageBox.qml");
    if (component.status === Component.Ready) {
        var dialog = component.createObject(parent);
        dialog.myIndex = index
        dialog.caption = myWindowSequenceConfiguration[index]["title"];
        dialog.message = myWindowSequenceConfiguration[index]["text"];
        dialog.showNextWindowFunc = showWindow
        dialog.show();
    }
}

function startTheShow() {
    showWindow(0)
}

好的,我想出了主题中的另一个变体:

MessageBox.qml:

Item {
...
    property var acceptedFuncParams
    property var canceledFuncParams
    property var acceptedFunc
    property var canceledFunc
    Button {
        id: acceptedButton
        onClicked: { acceptedFunc(acceptedFuncParams) }
    }
    Button {
        id: canceledButton
        onClicked: { canceledFunc(canceledFuncParams) }
    }
...
}

utilizingQml.qml:

property var myWindowSequenceConfiguration: [
    { "title" : "Title 1", "text" : "Text 1" },
    { "title" : "Title 2", "text" : "Text 2" },
    ...
]

function showWindow(index) {
    var component = Qt.createComponent("MessageBox.qml");
    if (component.status === Component.Ready) {
        var dialog = component.createObject(parent);
        dialog.caption = myWindowSequenceConfiguration[index]["title"];
        dialog.message = myWindowSequenceConfiguration[index]["text"];
        dialog.acceptedFuncParams = index+1
        dialog.acceptedFunc = showWindow
        dialog.canceledFunc = function() { ...do something here... }
        dialog.show();
    }
}

function startTheShow() {
    showWindow(0)
}