# Copyright 2019 miruka # This file is part of harmonyqml, licensed under GPLv3. import logging import sys from pathlib import Path from typing import Generator, Optional from PyQt5.QtCore import QFileSystemWatcher, QObject, QTimer from PyQt5.QtGui import QGuiApplication from PyQt5.QtQml import QQmlApplicationEngine from .__about__ import __doc__ from .backend import DummyBackend # logging.basicConfig(level=logging.INFO) class Engine(QQmlApplicationEngine): def __init__(self, app: QGuiApplication, debug: bool = False, parent: Optional[QObject] = None) -> None: super().__init__(parent) self.app = app self.backend = DummyBackend() self.app_dir = Path(sys.argv[0]).resolve().parent # Set QML properties self.rootContext().setContextProperty("Engine", self) self.rootContext().setContextProperty("Backend", self.backend) # Connect Qt signals self.quit.connect(self.app.quit) # Make SIGINT (ctrl-c) work self._sigint_timer = QTimer() self._sigint_timer.timeout.connect(lambda: None) self._sigint_timer.start(100) # Setup UI live-reloading when a file is edited if debug: self._watcher = QFileSystemWatcher() self._watcher.directoryChanged.connect(lambda _: self.reload_qml()) self._watcher.addPath(str(self.app_dir)) for _dir in list(self._recursive_dirs_in(self.app_dir)): self._watcher.addPath(str(_dir)) # Load QML page and show window self.load(str(self.app_dir / "components" / "Window.qml")) def show_window(self) -> None: self.rootObjects()[0].show() sys.exit(self.app.exec()) def _recursive_dirs_in(self, path: Path) -> Generator[Path, None, None]: for item in path.iterdir(): if item.is_dir() and item.name != "__pycache__": yield item yield from self._recursive_dirs_in(item) def reload_qml(self) -> None: self.clearComponentCache() loader = self.rootObjects()[0].findChild(QObject, "UILoader") source = loader.property("source") loader.setProperty("source", None) loader.setProperty("source", source) logging.info("Reloaded: %s", source)