diff --git a/.gitignore b/.gitignore index 0e687ffd3ce1615797cea8bfe261d04cc96f5b75..f920881f1cb87f7fd333848712074c2786c4579c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ # Python __pycache__/ -dist/ \ No newline at end of file +dist/ +build/ +*.spec \ No newline at end of file diff --git a/README.md b/README.md index f0a62e82d9e2e78ae20bc360474fd5571c7b1411..9088fecdd43daa7b6f6a88e5874b027b27bd439c 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,12 @@ poetry run controller ![UI](img/ms210_ui.png) +### Build executable + +```bash +poetry run pyinstaller --noconsole -F /app/ms210_controller.py +``` + ## Add the MS210 package Instructions to add the MS210 package to your project diff --git a/app/ms210_controller.py b/app/ms210_controller.py index 6f88cc63239c88a0a800190ba1b818c5e01ec266..51f4bc3a0a76cdf5bc4957938030556981eb716e 100644 --- a/app/ms210_controller.py +++ b/app/ms210_controller.py @@ -1,4 +1,5 @@ import sys +import platform from typing import Literal from PyQt6.QtGui import QCloseEvent @@ -23,8 +24,13 @@ class Window(QMainWindow, Ui_MainWindow): ports = serial.tools.list_ports.comports() for port in ports: - if "USB" in port.name: - self.port_cb.addItem(port.name) + if platform.system() == "Linux": + if "USB" in port.name: + self.port_cb.addItem(f"/dev/{port.name}") + elif platform.system() == "Windows": + if "COM" in port.name: + self.port_cb.addItem(port.name) + def __setup_signals(self): self.port_cb.currentIndexChanged.connect(self.port_select_cb) @@ -83,9 +89,10 @@ class Window(QMainWindow, Ui_MainWindow): return try: - self._ms210 = MS210(f"/dev/{self.port_cb.currentText()}") + self._ms210 = MS210(self.port_cb.currentText()) except MS210InitFailed as ex: self.error_msg(f"Failed to connect to MS210: {ex}") + self.port_cb.setCurrentIndex(0) self._ms210 = None return diff --git a/poetry.lock b/poetry.lock old mode 100644 new mode 100755 index 7328805a7cd11e8781f346d7bfd59c62a7e6f554..5abbca279af5d5179412adf516728f3d576de364 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,11 @@ +[[package]] +name = "altgraph" +version = "0.17.4" +description = "Python graph (network) package" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "astroid" version = "3.1.0" @@ -74,6 +82,17 @@ python-versions = ">=3.8.0" [package.extras] colors = ["colorama (>=0.4.6)"] +[[package]] +name = "macholib" +version = "1.16.3" +description = "Mach-O header analysis and editing" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +altgraph = ">=0.17" + [[package]] name = "mccabe" version = "0.7.0" @@ -106,6 +125,14 @@ category = "dev" optional = false python-versions = ">=3.8" +[[package]] +name = "pefile" +version = "2023.2.7" +description = "Python PE parsing module" +category = "dev" +optional = false +python-versions = ">=3.6.0" + [[package]] name = "platformdirs" version = "4.2.0" @@ -118,6 +145,39 @@ python-versions = ">=3.8" docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +[[package]] +name = "pyinstaller" +version = "6.5.0" +description = "PyInstaller bundles a Python application and all its dependencies into a single package." +category = "dev" +optional = false +python-versions = "<3.13,>=3.8" + +[package.dependencies] +altgraph = "*" +macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""} +packaging = ">=22.0" +pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""} +pyinstaller-hooks-contrib = ">=2024.3" +pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""} +setuptools = ">=42.0.0" + +[package.extras] +completion = ["argcomplete"] +hook_testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"] + +[[package]] +name = "pyinstaller-hooks-contrib" +version = "2024.3" +description = "Community maintained hooks for PyInstaller" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +packaging = ">=22.0" +setuptools = ">=42.0.0" + [[package]] name = "pylint" version = "3.1.0" @@ -222,6 +282,14 @@ python-versions = ">=3.8" [package.extras] cli = ["click (>=5.0)"] +[[package]] +name = "pywin32-ctypes" +version = "0.2.2" +description = "A (partial) reimplementation of pywin32 using ctypes/cffi" +category = "dev" +optional = false +python-versions = ">=3.6" + [[package]] name = "qt6-applications" version = "6.4.3.2.3" @@ -242,6 +310,19 @@ python-versions = ">=3.7" click = "*" qt6-applications = ">=6.4.3.2.2,<6.4.3.3" +[[package]] +name = "setuptools" +version = "69.1.1" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" +optional = false +python-versions = ">=3.8" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "tomli" version = "2.0.1" @@ -268,10 +349,14 @@ python-versions = ">=3.8" [metadata] lock-version = "1.1" -python-versions = "^3.10" -content-hash = "5c5b64c360238d047ead8cb0b9f4a25f0af1e8b4baaf737fad2838b3db4dc40f" +python-versions = ">=3.10,<3.13" +content-hash = "750261a91600664ea53716aedb9f718bae5d79383b9f8178e43f499cc8484e15" [metadata.files] +altgraph = [ + {file = "altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"}, + {file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"}, +] astroid = [ {file = "astroid-3.1.0-py3-none-any.whl", hash = "sha256:951798f922990137ac090c53af473db7ab4e70c770e6d7fae0cec59f74411819"}, {file = "astroid-3.1.0.tar.gz", hash = "sha256:ac248253bfa4bd924a0de213707e7ebeeb3138abeb48d798784ead1e56d419d4"}, @@ -316,6 +401,10 @@ isort = [ {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, ] +macholib = [ + {file = "macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c"}, + {file = "macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30"}, +] mccabe = [ {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, @@ -332,10 +421,32 @@ pathspec = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] +pefile = [ + {file = "pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6"}, + {file = "pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc"}, +] platformdirs = [ {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, ] +pyinstaller = [ + {file = "pyinstaller-6.5.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:81ec15c0deb8c7a0f95bea85b49eecc2df1bdeaf5fe487a41d97de6b0ad29dff"}, + {file = "pyinstaller-6.5.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:5f432f3fdef053989e0a44134e483131c533dab7637e6afd80c3f7c26e6dbcc9"}, + {file = "pyinstaller-6.5.0-py3-none-manylinux2014_i686.whl", hash = "sha256:6ffd76a0194dac4df5e66dcfccc7b597f3eaa40ef9a3f63548f260aa2c187512"}, + {file = "pyinstaller-6.5.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:a54968df2228f0128607b1dced41bbff94149d459987fb5cd1a41893e9bb85df"}, + {file = "pyinstaller-6.5.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:0dae0edbe6d667b6b0ccd8c97a148f86474a82da7ce582296f9025f4c7242ec6"}, + {file = "pyinstaller-6.5.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:7c76bfcb624803c311fa8fb137e4780d0ec86d11b7d90a8f43f185e2554afdcc"}, + {file = "pyinstaller-6.5.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:6cfee8a74ea2d3a1dc8e99e732a87b314739dc14363778143caac31f8aee9039"}, + {file = "pyinstaller-6.5.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:9d828213aea5401bb33a36ca396f8dc76a59a25bce1d76a13c9ad94ba29fbe42"}, + {file = "pyinstaller-6.5.0-py3-none-win32.whl", hash = "sha256:61865eee5e0d8f8252722f6d001baec497b7cee79ebe62c33a6ba86ba0c7010d"}, + {file = "pyinstaller-6.5.0-py3-none-win_amd64.whl", hash = "sha256:e1266498893ce1d6cc7337e8d2acbf7905a10ed2b7c8377270117d6b7b922fc4"}, + {file = "pyinstaller-6.5.0-py3-none-win_arm64.whl", hash = "sha256:1b3b7d6d3b18d76a833fd5a4d7f4544c5e2c2a4db4a728ea191e62f69d5cc33c"}, + {file = "pyinstaller-6.5.0.tar.gz", hash = "sha256:b1e55113c5a40cb7041c908a57f212f3ebd3e444dbb245ca2f91d86a76dabec5"}, +] +pyinstaller-hooks-contrib = [ + {file = "pyinstaller-hooks-contrib-2024.3.tar.gz", hash = "sha256:d18657c29267c63563a96b8fc78db6ba9ae40af6702acb2f8c871df12c75b60b"}, + {file = "pyinstaller_hooks_contrib-2024.3-py2.py3-none-any.whl", hash = "sha256:6701752d525e1f4eda1eaec2c2affc206171e15c7a4e188a152fcf3ed3308024"}, +] pylint = [ {file = "pylint-3.1.0-py3-none-any.whl", hash = "sha256:507a5b60953874766d8a366e8e8c7af63e058b26345cfcb5f91f89d987fd6b74"}, {file = "pylint-3.1.0.tar.gz", hash = "sha256:6a69beb4a6f63debebaab0a3477ecd0f559aa726af4954fc948c51f7a2549e23"}, @@ -403,6 +514,10 @@ python-dotenv = [ {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, ] +pywin32-ctypes = [ + {file = "pywin32-ctypes-0.2.2.tar.gz", hash = "sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60"}, + {file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"}, +] qt6-applications = [ {file = "qt6_applications-6.4.3.2.3-py3-none-macosx_10_14_universal2.whl", hash = "sha256:aa4d1562ab154e32809045a08b7c2cd6fe86f061bbbe179eaba3580397168005"}, {file = "qt6_applications-6.4.3.2.3-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:f9c47faf46a71cf1b61b6ffd1908783454c99742fbfd59c49d523f29f035467e"}, @@ -411,6 +526,10 @@ qt6-applications = [ qt6-tools = [ {file = "qt6_tools-6.4.3.1.3-py3-none-any.whl", hash = "sha256:dd01cdf830ec8a14f353b7f6d0b81eb4d7472b86f9fa8e872c8ed9c3465726e3"}, ] +setuptools = [ + {file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"}, + {file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"}, +] tomli = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, diff --git a/pyproject.toml b/pyproject.toml old mode 100644 new mode 100755 index 69c8f13272648de783d78ff7c4a1854976b5fecf..29b498956221868cf83e4662241e4be89c440e03 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "ms210" -version = "0.1.0" +version = "1.0.0" description = "Drive the MS210 device" authors = ["Mattia Gallacchi "] readme = "README.md" @@ -9,13 +9,14 @@ packages = [ ] [tool.poetry.dependencies] -python = "^3.10" +python = ">=3.10,<3.13" pyserial = "^3.5" [tool.poetry.group.dev.dependencies] pyqt6-tools = "^6.4.2.3.3" PyQt6 = "6.4.2" +pyinstaller = "^6.5.0" [tool.poetry.group.lint.dependencies]