在我的项目中,我使用从 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/