From b55b2a11fec0dee560c2722451f500a22f7c9714 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 00:50:47 +0200 Subject: [PATCH 1/3] Starting main tests --- LogarithmPlotter/logarithmplotter.py | 101 +++++++++++------- .../qml/eu/ad5001/LogarithmPlotter/js/io.mjs | 2 +- tests/python/test_main.py | 16 +++ 3 files changed, 77 insertions(+), 42 deletions(-) create mode 100644 tests/python/test_main.py diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index ae908f5..975f471 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -16,18 +16,18 @@ * along with this program. If not, see . """ +from os import getcwd, chdir, environ, path +from platform import release as os_release +from sys import path as sys_path +from sys import platform, argv, exit +from tempfile import TemporaryDirectory from time import time -from PySide6.QtWidgets import QApplication -from PySide6.QtQml import QQmlApplicationEngine -from PySide6.QtCore import Qt, QTranslator, QLocale +from PySide6.QtCore import QTranslator, QLocale from PySide6.QtGui import QIcon - -from tempfile import TemporaryDirectory -from os import getcwd, chdir, environ, path, remove, close -from platform import release as os_release -from sys import platform, argv, version as sys_version, exit -from sys import path as sys_path +from PySide6.QtQml import QQmlApplicationEngine +from PySide6.QtQuickControls2 import QQuickStyle +from PySide6.QtWidgets import QApplication start_time = time() @@ -48,10 +48,7 @@ from LogarithmPlotter.util.helper import Helper from LogarithmPlotter.util.latex import Latex from LogarithmPlotter.util.js import PyJSValue -config.init() - - -def get_linux_theme(): +def get_linux_theme() -> str: des = { "KDE": "Fusion", "gnome": "Basic", @@ -59,59 +56,59 @@ def get_linux_theme(): "mate": "Fusion", } if "XDG_SESSION_DESKTOP" in environ: - return des[environ["XDG_SESSION_DESKTOP"]] if environ["XDG_SESSION_DESKTOP"] in des else "Fusion" + if environ["XDG_SESSION_DESKTOP"] in des: + return des[environ["XDG_SESSION_DESKTOP"]] + return "Fusion" else: # Android return "Material" -def run(): - if not 'QT_QUICK_CONTROLS_STYLE' in environ: - environ["QT_QUICK_CONTROLS_STYLE"] = { - "linux": get_linux_theme(), - "freebsd": get_linux_theme(), - "win32": "Universal" if os_release == "10" else "Fusion", - "cygwin": "Fusion", - "darwin": "macOS" - }[platform] +def get_platform_qt_style(os) -> str: + return { + "linux": get_linux_theme(), + "freebsd": get_linux_theme(), + "win32": "Universal" if os_release() in ["10", "11", "12", "13", "14"] else "Windows", + "cygwin": "Fusion", + "darwin": "macOS" + }[os] - dep_time = time() - print("Loaded dependencies in " + str((dep_time - start_time) * 1000) + "ms.") - icon_fallbacks = QIcon.fallbackSearchPaths(); +def register_icon_directories() -> None: + icon_fallbacks = QIcon.fallbackSearchPaths() base_icon_path = path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "icons") icon_fallbacks.append(path.realpath(path.join(base_icon_path, "common"))) icon_fallbacks.append(path.realpath(path.join(base_icon_path, "objects"))) icon_fallbacks.append(path.realpath(path.join(base_icon_path, "history"))) icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings"))) icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings", "custom"))) - QIcon.setFallbackSearchPaths(icon_fallbacks); + QIcon.setFallbackSearchPaths(icon_fallbacks) + +def create_qapp() -> QApplication: app = QApplication(argv) app.setApplicationName("LogarithmPlotter") app.setDesktopFileName("eu.ad5001.LogarithmPlotter.desktop") app.setOrganizationName("Ad5001") app.styleHints().setShowShortcutsInContextMenus(True) app.setWindowIcon(QIcon(path.realpath(path.join(getcwd(), "logarithmplotter.svg")))) + return app + +def install_translation(app: QApplication) -> QTranslator: # Installing translators translator = QTranslator() # Check if lang is forced. forcedlang = [p for p in argv if p[:7] == "--lang="] locale = QLocale(forcedlang[0][7:]) if len(forcedlang) > 0 else QLocale() if translator.load(locale, "lp", "_", path.realpath(path.join(getcwd(), "i18n"))): - app.installTranslator(translator); + app.installTranslator(translator) + return translator - # Installing macOS file handler. - macos_file_open_handler = None - if platform == "darwin": - macos_file_open_handler = native.MacOSFileOpenHandler() - app.installEventFilter(macos_file_open_handler) - engine = QQmlApplicationEngine() +def create_engine(helper: Helper, latex: Latex, dep_time: float) -> tuple[QQmlApplicationEngine, PyJSValue]: global tmpfile - helper = Helper(pwd, tmpfile) - latex = Latex(tempdir) + engine = QQmlApplicationEngine() js_globals = PyJSValue(engine.globalObject()) js_globals.Modules = engine.newObject() js_globals.Helper = engine.newQObject(helper) @@ -119,15 +116,37 @@ def run(): engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) engine.rootContext().setContextProperty("StartTime", dep_time) - app.translate("About", "About LogarithmPlotter") - # FOR SOME REASON, if this isn't included, Qt refuses to load the QML file. - engine.addImportPath(path.realpath(path.join(getcwd(), "qml"))) engine.load(path.realpath(path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "LogarithmPlotter.qml"))) - if not engine.rootObjects(): + return engine, js_globals + + +def run(): + config.init() + + if not 'QT_QUICK_CONTROLS_STYLE' in environ: + QQuickStyle.setStyle(get_platform_qt_style(platform)) + + dep_time = time() + print("Loaded dependencies in " + str((dep_time - start_time) * 1000) + "ms.") + + register_icon_directories() + app = create_qapp() + translator = install_translation(app) + + # Installing macOS file handler. + macos_file_open_handler = None + if platform == "darwin": + macos_file_open_handler = native.MacOSFileOpenHandler() + app.installEventFilter(macos_file_open_handler) + + helper = Helper(pwd, tmpfile) + latex = Latex(tempdir) + engine, js_globals = create_engine(helper, latex, dep_time) + + if len(engine.rootObjects()) == 0: # No root objects loaded print("No root object", path.realpath(path.join(getcwd(), "qml"))) - print(path.realpath(path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "LogarithmPlotter.qml"))) exit(-1) # Open the current diagram diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs index 396ada8..4bc76b5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs @@ -34,7 +34,7 @@ class IOAPI extends Module { /** * Initializes module with QML elements. - * @param {LogarithmPlotter} rootElement + * @param {{width: number, height: number, updateObjectsLists: function()}} rootElement * @param {Settings} settings * @param {{show: function(string)}} alert */ diff --git a/tests/python/test_main.py b/tests/python/test_main.py new file mode 100644 index 0000000..1dfbcbb --- /dev/null +++ b/tests/python/test_main.py @@ -0,0 +1,16 @@ +import pytest + +from LogarithmPlotter.logarithmplotter import get_linux_theme + +THEMES = [ + "Basic", + "Universal", + "Material", + "Fusion", + "Windows", + "macOS" +] + +class TestMain: + def test_themes(self): + get_linux_theme() \ No newline at end of file From e68411e93c5b2b1538de305acb30a0cf8709865b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 00:51:16 +0200 Subject: [PATCH 2/3] Fixing typos --- linux/logarithmplotter.desktop | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/logarithmplotter.desktop b/linux/logarithmplotter.desktop index 56a0b14..00c871f 100644 --- a/linux/logarithmplotter.desktop +++ b/linux/logarithmplotter.desktop @@ -7,9 +7,9 @@ GenericName[de]=2D-Grafiksoftware mit logarithmischer Skalierung GenericName[fr]=Logiciel de traçage à l'échelle logarithmique GenericName[hu]=Síkbeli ábrázolásszoftver GenericName[no]=2D-plotterprogramvare -Comment=Create BODE diagrams, sequences and distribution functions +Comment=Create Bode diagrams, sequences and distribution functions Comment[de]=Erstellung von Bode-Diagramms, Folgen und Verteilungsfunktionen -Comment[fr]=Créer des diagrammes de BODE, des suites et des fonctions de répartition +Comment[fr]=Créer des diagrammes de Bode, des suites et des fonctions de répartition Comment[hu]=Bode-ábrák, sorozatok és újraosztási függvények létrehozása TryExec=logarithmplotter From a250f532d9c9e3322b9fa2ea03ab532339a067d3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 00:51:28 +0200 Subject: [PATCH 3/3] Adding pyside6-addons as dependency until https://bugreports.qt.io/browse/PYSIDE-2871 is resolved. --- poetry.lock | 19 ++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index cf83dea..e2ba8cf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -259,6 +259,23 @@ importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} packaging = ">=22.0" setuptools = ">=42.0.0" +[[package]] +name = "pyside6-addons" +version = "6.7.2" +description = "Python bindings for the Qt cross-platform application and UI framework (Addons)" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "PySide6_Addons-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:90b995efce61058d995c603ea480a9a3054fe8206739dcbc273fc3b53d40650f"}, + {file = "PySide6_Addons-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:94b9bf6a2a4a7ac671e1776633e50d51326c86f4184f1c6e556f4dd5498fd52a"}, + {file = "PySide6_Addons-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:22979b1aa09d9cf1d7a86c8a9aa0cb4791d6bd1cc94f96c5b6780c5ef8a9e34e"}, + {file = "PySide6_Addons-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:ebf549eb25998665d8e4ec24014fbbd37bebc5ecdcb050b34db1e1c03e1bf81d"}, +] + +[package.dependencies] +PySide6-Essentials = "6.7.2" +shiboken6 = "6.7.2" + [[package]] name = "pyside6-essentials" version = "6.7.2" @@ -421,4 +438,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "4693a671e927103ceeb946f688b84fdc56b8b39b2cd772d8d32475e1236d8a07" +content-hash = "083111ed37f3ef23de75a56eaf4c6fdda954b6005c5ee0922aad4470e2a36738" diff --git a/pyproject.toml b/pyproject.toml index bf23573..a7aa8cc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ package-mode = false [tool.poetry.dependencies] python = ">=3.9,<3.13" PySide6-Essentials = "^6.7.2" +pyside6-addons = "^6.7.2" [tool.poetry.group.dev.dependencies] pyinstaller = "^6.10.0"