我希望在FileDialog中用户接受文件名后应用程序处理任务时显示busyindicator,但看起来主要线程被filedialog阻止。因此无法显示busyindicator。我该如何解决?感谢
代码如下:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
ApplicationWindow {
title: qsTr("Hello World")
id: root
width: 640
height: 480
menuBar: MenuBar {
Menu {
title: qsTr("&File")
MenuItem {
text: qsTr("E&xit")
onTriggered: Qt.quit();
}
}
}
MainForm {
anchors.fill: parent
button1.onClicked: {
exportXlsxDialog.open()
}
FileDialog {
id: exportXlsxDialog
title: qsTr("Please choose a xslx file")
nameFilters: [ "Excel 2007-2013 (*.xlsx)" ]
selectExisting: false
onAccepted: {
busyIndicator.running = true
sleep(10000)
console.log(fileUrl)
busyIndicator.running = false
}
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
}
BusyIndicator {
id: busyIndicator
z: 99
anchors.centerIn: parent
running: false
}
}
}
答案 0 :(得分:0)
我认为问题在于你的sleep()
函数没有给BusyIndicator
一个机会显示,可能是因为它不会让Qt的事件循环旋转。
最好的解决方案可能是使用WorkerScript,但如果你很懒,你可以使用它:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
ApplicationWindow {
title: qsTr("Hello World")
id: root
width: 640
height: 480
Timer {
id: expensiveOperationDelay
interval: 1
onTriggered: sleep(2000)
}
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
busyIndicator.running = false
}
Button {
text: "Click"
onClicked: {
busyIndicator.running = true
expensiveOperationDelay.start()
// sleep(2000)
}
}
BusyIndicator {
id: busyIndicator
z: 99
anchors.centerIn: parent
running: false
}
}
我简化了你的例子,因为没有必要用对话来证明这个问题。
这将启动昂贵操作的责任推到Timer
。我给它一个最小的间隔,导致事件被处理(我认为0
的间隔会导致,但显然不会),以便显示指标。我还必须将指示器的隐藏移动到sleep()
函数的末尾,因为如果我将它保留在原来的位置,它将在它被渲染之前再次被隐藏。