在我的项目中,我使用从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()的同步调用,或者可能是其他一些想法,也许是一些信号量或类似的东西。
答案 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)
}