I am currently learning QML.jl, IMO matured GUI framework for Julia. It’s documentation is quite limited so I decided that first prototype in PySide6(which has lot of resources) then port the code to Julia.
I am currently stuck on porting code with Signal based communiction from Python to Julia.
PySide6 example
Below is a minimal example of a live digital clock.
Python emits the current time every second to QML using a Qt signal.
# basicclock.py
import sys
from datetime import datetime
from PySide6.QtCore import Property, QObject, QTimer, QUrl, Signal
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtWidgets import QApplication
class Clock(QObject):
timeChanged = Signal(str)
def __init__(self):
super().__init__()
self._time = ""
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_time)
self.timer.start(1000)
self.update_time()
def update_time(self):
self._time = datetime.now().strftime("%H:%M:%S")
self.timeChanged.emit(self._time)
def get_time(self):
return self._time
time = Property(str, get_time, notify=timeChanged)
if __name__ == "__main__":
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
clock = Clock()
engine.rootContext().setContextProperty("clock", clock)
engine.load(QUrl("basicclock.qml"))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec())
Corresponding QML
// basicclock.qml
import QtQuick
import QtQuick.Controls
ApplicationWindow {
visible: true
width: 300
height: 150
title: "Digital Clock"
Rectangle {
anchors.fill: parent
color: "#2E3440"
Text {
id: timeText
anchors.centerIn: parent
text: clock.time
font.pixelSize: 48
color: "#D8DEE9"
}
}
}
QML.jl version (current workaround)
I can recreate the same UI in QML.jl, but only by moving the timer logic into QML instead of keeping it in Julia.
# basicclock.jl
using QML
using Dates
clock = JuliaPropertyMap("time"=>Dates.format(now(), "HH:MM:SS"))
function update_clock()
new_time = Dates.format(now(), "HH:MM:SS")
clock["time"] = new_time
end
@qmlfunction update_clock
function @main(ARGS)
loadqml("basicclock.qml", clock=clock)
exec()
end
Corresponding QML
// basicclock.qml
import QtQuick
import QtQuick.Controls
import jlqml
ApplicationWindow {
visible: true
width: 300
height: 150
title: "Digital Clock"
Rectangle {
anchors.fill: parent
color: "#2E3440"
Text {
id: timeText
anchors.centerIn: parent
text: clock.time
font.pixelSize: 48
color: "#D8DEE9"
}
}
Timer {
interval: 1000
running: true
repeat: true
onTriggered: Julia.update_clock()
}
}
While this approach works, I’m unsure whether moving application logic into QML solely to update state is the intended or recommended design.
Questions
- How to emit data from background running Julia task to Qml component?
- Is there any equivalent to PySide6
Signalclass and it’s methods in QML.jl or does QML.jl provides different paradigm for this? - Is it possible to achieve the same behavior as the PySide6 example using a Julia Timer or QTimer, without moving the timer logic into QML?
Any guidance and recommended practices would be greatly appreciated.