[исходный код проекта можно скачать здесь]
Создадим новый проект в Clickable, в терминале вводим команду:
clickable create
Выбираем тип проекта Python и заполняем:
Title [App Title]: Progress Bar
App Name [appname]: exemple-progress-bar
В папке с проектом находи Main.qml удаляем все лишнее - Python объект, Label в Page.
Теперь создадим интерфейс:
Text {
id: label1
text: qsTr("Download...")
color: "#5E2750"
anchors{
verticalCenterOffset: -units.gu(4)
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: units.gu(1)
right: parent.right
}
font.pixelSize: units.gu(2)
}
Rectangle {
height: units.gu(5)
color: "white"
anchors
{
verticalCenter: parent.verticalCenter
right: parent.right
left: parent.left
}
Rectangle {
color: "#AEA79F"
anchors.fill: parent
border.width: units.gu(1)
radius: units.gu(1.5)
border.color: "white"
}
Rectangle {
id: progressbar1
color: "#E95420"
property real value: 0
anchors{
rightMargin: parent.width/100*(100-value)
fill: parent
}
border.width: units.gu(1)
radius: units.gu(1.5)
border.color: "white"
}
}
Таким образом мы создали Label, для отображения состояния процесса и свой прогресс бар.
Наш прогресс бар это два прямоугольника- полоса состояния и его подложка. Для того, что бы с ним была возможность взаимодействовать назначаем id: progressbar1. Так же добавляем переменную для взаимодействия value. В зависимости от значения этой переменной будет меняться правый отступ от края, по формуле - parent.width/100*(100-value).
Теперь добавим объект Python:
Python {
id: python1
Component.onCompleted: {
addImportPath(Qt.resolvedUrl('../src/'));
setHandler('progress', function(ratio) {
progressbar1.value = ratio;
});
setHandler('finished', function() {
label1.text = qsTr("Download complete");
progressbar1.color = "#5E2750";
});
importModule('example', function () {
startDownload();
});
}
function startDownload() {
progressbar1.value = 0.0;
call('example.downloader.download', function() {});
}
onError: {
console.log('python error: ' + traceback);
}
}
Мы создали 2 события для взаимодействия - progress и finished. Когда мы передаем переменную в progress, у нас будет меняться значение progressbar1.value. А когда мы закончим, через вызов finished, мы выведем сообщение "Download complete" и изменим цвет прогресс бара на фиолетовый.
Что бы начать загрузку мы создали функцию startDownload(). Ее можно вызвать в любом месте кода, через python1.startDownload()(Например при нажатии кнопки). В этом коде эта функция вызывается при инициализации скрипта example.
Теперь переходим в папку src и редактируем example.py:
import pyotherside
import time
import threading
def slow_function():
for i in range(100):
pyotherside.send('progress', i)
time.sleep(0.2)
pyotherside.send('finished')
class Downloader:
def __init__(self):
self.bgthread = threading.Thread()
def download(self):
if self.bgthread.is_alive():
return
self.bgthread = threading.Thread(target=slow_function)
self.bgthread.start()
downloader = Downloader()
В этом примере создается новый класс Downloader. При инициализации он создаст новый объект для потока, который и будет взаимодействовать с прогресс баром. Этот процесс можно запустить вручную или повторно, через функцию download.
Для того, что бы с прогресс баром взаимодействовал всегда один процесс, пишем проверку if self.bgthread.is_alive(). В случае если процесс уже запущен, она не создаст новый поток.
Теперь мы можем создать этот объект downloader = Downloader()
В потоке slow_function() мы взаимодействуем с QML через функцию pyotherside.send(). Сперва отправляем значения в progress(0-100), а затем вызываем событие finished.
Осталось только запустить код.