javascript - 同步Window.show()

标签 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是用户单击Ok按钮时发出的MessageBox.qml信号。

但是这个结构太复杂而且不太清晰。另外我不知道如果使用点击取消该怎么办。

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

最佳答案

据我迄今为止从评论中了解到的,似乎同步/异步(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?... }
    }
...
}

利用Qml.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) }
    }
...
}

利用Qml.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)
}

关于javascript - 同步Window.show(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35283044/

相关文章:

使用 Qt 进行 C++0x 编程

c++ - 如何在QLabel的特定坐标中设置QPixmap?

c++ - QML 信号连接

android - 在 QML 中访问 Android 系统图像

JAVASCRIPT:如何删除 json 对象中的 json 对象?

javascript - 如何使用 jQuery 获取页面向下滚动的像素数量?

javascript - 如何使用 setInterval 自动点击 slider ?

javascript - 将字符串数组转换为一个数组JS

qt - 构建后更改Qt安装路径?

Qt QML 设置未保存/应用