├── son
└── beep.wav
├── i18n
├── cn5X.en.qm
├── cn5X.fr.qm
├── flags
│ └── flag_fr.svg
├── Makefile
├── cn5X_locales.xsd
├── cn5X_locales.xml
└── cn5X.pro
├── images
├── XYZAB-32.ico
├── XYZAB-48.ico
├── screenshots
│ ├── cn5X_screenShot_00.png
│ ├── cn5X_screenShot_01.png
│ ├── cn5X_screenShot_02.png
│ ├── cn5X_screenShot_03.png
│ ├── cn5X_screenShot_04.png
│ ├── cn5X_screenShot_05.png
│ ├── cn5X_screenShot_06.png
│ └── cn5X_screenShot_07.png
├── Vide-60x60.svg
├── Fleche00.svg
├── btnJogNone.svg
├── btnClose.svg
├── btnJogPlusX.svg
├── btnJogPlusY.svg
├── btnJogMoinsY.svg
├── btnJogMoinsC.svg
├── btnJogMoinsX.svg
├── btnJogPlusC.svg
├── btnJogMoinsZ.svg
├── btnJogPlusZ.svg
├── btnJogMoinsA.svg
├── btnJogPlusA.svg
├── btnJogPlusB.svg
├── btnJogMoinsB.svg
├── btnResetSpeed.svg
├── btnProbeInX-.svg
├── btnProbeInX+.svg
├── btnProbeOutX-.svg
├── btnProbeInY-.svg
├── btnProbeInY+.svg
├── btnProbeOutX+.svg
├── btnProbeOutY-.svg
├── btnProbeOutY+.svg
├── chkBoxDisabledUnChecked.svg
├── chkBoxUnChecked.svg
├── btnProbeOutCercle.svg
├── btnProbeZ-.svg
├── btnJogX.svg
├── btnJogY.svg
├── btnKillAlarm.svg
├── btnJogZ.svg
├── btnProbeInCercle.svg
├── btnJogC.svg
├── chkBoxDisabledChecked.svg
├── btnRefresh.svg
├── btnJogB.svg
├── ledBleuEteinte.svg
├── btnJogA.svg
├── ledVerteEteinte.svg
├── chkBoxChecked.svg
├── ledBleuAlumee.svg
├── ledRougeEteinte.svg
├── ledVerteAlumee.svg
└── btnG28.svg
├── fonts
├── DSEG14Classic.ttf
├── LEDCalculator.ttf
├── DSEG14ClassicMini.ttf
└── fontsRessources.qrc
├── .github
└── FUNDING.yml
├── .gitignore
├── Makefile
├── gcodeQLineEdit.py
├── cn5X_beep.py
├── cnQLabel.py
├── setup.py
├── compilOptions.py
├── README.md
├── grblComStack.py
├── speedOverrides.py
├── cn5X_apropos.py
├── grblJog.py
├── qwHorloge.ui
└── cnled.py
/son/beep.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/son/beep.wav
--------------------------------------------------------------------------------
/i18n/cn5X.en.qm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/i18n/cn5X.en.qm
--------------------------------------------------------------------------------
/i18n/cn5X.fr.qm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/i18n/cn5X.fr.qm
--------------------------------------------------------------------------------
/images/XYZAB-32.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/images/XYZAB-32.ico
--------------------------------------------------------------------------------
/images/XYZAB-48.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/images/XYZAB-48.ico
--------------------------------------------------------------------------------
/fonts/DSEG14Classic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/fonts/DSEG14Classic.ttf
--------------------------------------------------------------------------------
/fonts/LEDCalculator.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/fonts/LEDCalculator.ttf
--------------------------------------------------------------------------------
/fonts/DSEG14ClassicMini.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/fonts/DSEG14ClassicMini.ttf
--------------------------------------------------------------------------------
/images/screenshots/cn5X_screenShot_00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/images/screenshots/cn5X_screenShot_00.png
--------------------------------------------------------------------------------
/images/screenshots/cn5X_screenShot_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/images/screenshots/cn5X_screenShot_01.png
--------------------------------------------------------------------------------
/images/screenshots/cn5X_screenShot_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/images/screenshots/cn5X_screenShot_02.png
--------------------------------------------------------------------------------
/images/screenshots/cn5X_screenShot_03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/images/screenshots/cn5X_screenShot_03.png
--------------------------------------------------------------------------------
/images/screenshots/cn5X_screenShot_04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/images/screenshots/cn5X_screenShot_04.png
--------------------------------------------------------------------------------
/images/screenshots/cn5X_screenShot_05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/images/screenshots/cn5X_screenShot_05.png
--------------------------------------------------------------------------------
/images/screenshots/cn5X_screenShot_06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/images/screenshots/cn5X_screenShot_06.png
--------------------------------------------------------------------------------
/images/screenshots/cn5X_screenShot_07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fra589/cn5X/HEAD/images/screenshots/cn5X_screenShot_07.png
--------------------------------------------------------------------------------
/fonts/fontsRessources.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | LEDCalculator.ttf
4 | DSEG14Classic.ttf
5 | DSEG14ClassicMini.ttf
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: Gauthier
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | build*/
14 | develop-eggs/
15 | dist/
16 | downloads/
17 | eggs/
18 | .eggs/
19 | lib/
20 | lib64/
21 | parts/
22 | sdist/
23 | var/
24 | wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .coverage
43 | .coverage.*
44 | .cache
45 | nosetests.xml
46 | coverage.xml
47 | *.cover
48 | .hypothesis/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 |
58 | # Flask stuff:
59 | instance/
60 | .webassets-cache
61 |
62 | # Scrapy stuff:
63 | .scrapy
64 |
65 | # Sphinx documentation
66 | docs/_build/
67 |
68 | # PyBuilder
69 | target/
70 |
71 | # Jupyter Notebook
72 | .ipynb_checkpoints
73 |
74 | # pyenv
75 | .python-version
76 |
77 | # celery beat schedule file
78 | celerybeat-schedule
79 |
80 | # SageMath parsed files
81 | *.sage.py
82 |
83 | # dotenv
84 | .env
85 |
86 | # virtualenv
87 | .venv
88 | venv/
89 | ENV/
90 |
91 | # Spyder project settings
92 | .spyderproject
93 | .spyproject
94 |
95 | # Rope project settings
96 | .ropeproject
97 |
98 | # mkdocs documentation
99 | /site
100 |
101 | # mypy
102 | .mypy_cache/
103 |
104 | # Geany project file
105 | cn5X.geany
106 |
107 | # old files
108 | *.old
109 |
110 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for cn5X++
2 |
3 | #''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
4 | # '
5 | # Copyright 2018 Gauthier Brière (gauthier.briere "at" gmail.com) '
6 | # '
7 | # This file is part of cn5X++ '
8 | # '
9 | # cn5X++ is free software: you can redistribute it and/or modify it '
10 | # under the terms of the GNU General Public License as published by '
11 | # the Free Software Foundation, either version 3 of the License, or '
12 | # (at your option) any later version. '
13 | # '
14 | # cn5X++ is distributed in the hope that it will be useful, but '
15 | # WITHOUT ANY WARRANTY; without even the implied warranty of '
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
17 | # GNU General Public License for more details. '
18 | # '
19 | # You should have received a copy of the GNU General Public License '
20 | # along with this program. If not, see . '
21 | # '
22 | #''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
23 |
24 | #-----------------------------------------------------------------------
25 | # Compile les fichiers de langue
26 | #-----------------------------------------------------------------------
27 |
28 | LANG_DIR=i18n
29 |
30 | all: lang
31 |
32 | lang: $(LANG_DIR)/*.qm $(LANG_DIR)/cn5X_locales.xml
33 | @(cd $(LANG_DIR) && $(MAKE))
34 |
35 | %.qm: %.ts cn5X.pro
36 |
--------------------------------------------------------------------------------
/images/Vide-60x60.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
62 |
--------------------------------------------------------------------------------
/i18n/flags/flag_fr.svg:
--------------------------------------------------------------------------------
1 |
2 |
67 |
--------------------------------------------------------------------------------
/i18n/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for cn5X++
2 |
3 | #''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
4 | # '
5 | # Copyright 2018 Gauthier Brière (gauthier.briere "at" gmail.com) '
6 | # '
7 | # This file is part of cn5X++ '
8 | # '
9 | # cn5X++ is free software: you can redistribute it and/or modify it '
10 | # under the terms of the GNU General Public License as published by '
11 | # the Free Software Foundation, either version 3 of the License, or '
12 | # (at your option) any later version. '
13 | # '
14 | # cn5X++ is distributed in the hope that it will be useful, but '
15 | # WITHOUT ANY WARRANTY; without even the implied warranty of '
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
17 | # GNU General Public License for more details. '
18 | # '
19 | # You should have received a copy of the GNU General Public License '
20 | # along with this program. If not, see . '
21 | # '
22 | #''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
23 |
24 | #-----------------------------------------------------------------------
25 | # Compile les fichiers .ui de QT Designer vers scripts Python
26 | # Compile les fichiers de ressources vers scripts Python
27 | #-----------------------------------------------------------------------
28 |
29 | SRC=$(wildcard *.ts)
30 | QMFILES=$(SRC:.ts=.qm)
31 |
32 | all: $(QMFILES)
33 |
34 | %.qm: %.ts
35 | lrelease cn5X.pro
36 |
37 | %.ts: ../*.py cn5X.pro
38 | lupdate cn5X.pro
39 |
40 |
--------------------------------------------------------------------------------
/gcodeQLineEdit.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 |
3 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
4 | ' '
5 | ' Copyright 2018-2024 Gauthier Brière (gauthier.briere "at" gmail.com) '
6 | ' '
7 | ' This file is part of cn5X++ '
8 | ' '
9 | ' cn5X++ is free software: you can redistribute it and/or modify it '
10 | ' under the terms of the GNU General Public License as published by '
11 | ' the Free Software Foundation, either version 3 of the License, or '
12 | ' (at your option) any later version. '
13 | ' '
14 | ' cn5X++ is distributed in the hope that it will be useful, but '
15 | ' WITHOUT ANY WARRANTY; without even the implied warranty of '
16 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
17 | ' GNU General Public License for more details. '
18 | ' '
19 | ' You should have received a copy of the GNU General Public License '
20 | ' along with this program. If not, see . '
21 | ' '
22 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
23 |
24 | from PyQt6 import QtCore, QtGui, QtWidgets
25 | from PyQt6.QtCore import pyqtSignal
26 |
27 |
28 | class gcodeQLineEdit(QtWidgets.QLineEdit):
29 | ''' QlineEdit avec ajout de l'envoi d'evennement KeyPressed
30 | '''
31 | keyPressed = pyqtSignal(QtGui.QKeyEvent)
32 |
33 |
34 | def __init__(self, parent=None):
35 | super().__init__(parent)
36 |
37 |
38 | def keyPressEvent(self, event):
39 | self.keyPressed.emit(event)
40 | return super().keyPressEvent(event)
41 |
42 |
--------------------------------------------------------------------------------
/cn5X_beep.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 |
3 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
4 | ' '
5 | ' Copyright 2018-2024 Gauthier Brière (gauthier.briere "at" gmail.com) '
6 | ' '
7 | ' This file: cn5X_beep.py, is part of cn5X++ '
8 | ' '
9 | ' cn5X++ is free software: you can redistribute it and/or modify it '
10 | ' under the terms of the GNU General Public License as published by '
11 | ' the Free Software Foundation, either version 3 of the License, or '
12 | ' (at your option) any later version. '
13 | ' '
14 | ' cn5X++ is distributed in the hope that it will be useful, but '
15 | ' WITHOUT ANY WARRANTY; without even the implied warranty of '
16 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
17 | ' GNU General Public License for more details. '
18 | ' '
19 | ' You should have received a copy of the GNU General Public License '
20 | ' along with this program. If not, see . '
21 | ' '
22 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
23 |
24 | import os
25 | from platform import system
26 | from playsound import playsound
27 |
28 | class cn5XBeeper():
29 | '''
30 | Emissions de bip sonores
31 | '''
32 | def __init__(self):
33 | super().__init__()
34 |
35 | self.__beepFile = os.path.join(os.path.dirname(__file__), "son/beep.wav")
36 |
37 |
38 | def beep(self, volume: float):
39 | '''
40 | Emission d'un beep sonore depuis le fichier beep.wav
41 | '''
42 | if system() == 'Windows':
43 | playsound(self.__beepFile, True)
44 | else:
45 | playsound(self.__beepFile, False)
46 |
47 |
--------------------------------------------------------------------------------
/i18n/cn5X_locales.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/images/Fleche00.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
69 |
--------------------------------------------------------------------------------
/cnQLabel.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 |
3 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
4 | ' '
5 | ' Copyright 2018-2024 Gauthier Brière (gauthier.briere "at" gmail.com) '
6 | ' '
7 | ' This file is part of cn5X++ '
8 | ' '
9 | ' cn5X++ is free software: you can redistribute it and/or modify it '
10 | ' under the terms of the GNU General Public License as published by '
11 | ' the Free Software Foundation, either version 3 of the License, or '
12 | ' (at your option) any later version. '
13 | ' '
14 | ' cn5X++ is distributed in the hope that it will be useful, but '
15 | ' WITHOUT ANY WARRANTY; without even the implied warranty of '
16 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
17 | ' GNU General Public License for more details. '
18 | ' '
19 | ' You should have received a copy of the GNU General Public License '
20 | ' along with this program. If not, see . '
21 | ' '
22 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
23 |
24 | import sys, os
25 | from PyQt6 import QtCore, QtGui, QtWidgets
26 | from PyQt6.QtCore import pyqtSignal
27 |
28 |
29 | class cnQLabel(QtWidgets.QLabel):
30 | '''
31 | QLabel avec gestion de click
32 | '''
33 |
34 | clicked = pyqtSignal(str, QtGui.QMouseEvent)
35 | doubleClick = pyqtSignal(str, QtGui.QMouseEvent)
36 |
37 | def __init__(self, parent=None):
38 | super(cnQLabel, self).__init__(parent=parent)
39 |
40 | def mouseReleaseEvent(self, e):
41 | super(cnQLabel, self).mouseReleaseEvent(e)
42 | self.clicked.emit(self.text(), e)
43 |
44 | def mouseDoubleClickEvent(self, e):
45 | super(cnQLabel, self).mouseDoubleClickEvent(e)
46 | self.doubleClick.emit(self.text(), e)
47 |
--------------------------------------------------------------------------------
/images/btnJogNone.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
70 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python3
2 | # -*- coding: UTF-8 -*-
3 |
4 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
5 | ' '
6 | ' Copyright 2018-2024 Gauthier Brière (gauthier.briere "at" gmail.com) '
7 | ' '
8 | ' This file is part of cn5X++ '
9 | ' '
10 | ' cn5X++ is free software: you can redistribute it and/or modify it '
11 | ' under the terms of the GNU General Public License as published by '
12 | ' the Free Software Foundation, either version 3 of the License, or '
13 | ' (at your option) any later version. '
14 | ' '
15 | ' cn5X++ is distributed in the hope that it will be useful, but '
16 | ' WITHOUT ANY WARRANTY; without even the implied warranty of '
17 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
18 | ' GNU General Public License for more details. '
19 | ' '
20 | ' You should have received a copy of the GNU General Public License '
21 | ' along with this program. If not, see . '
22 | ' '
23 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
24 |
25 | from cn5X_config import *
26 | from cx_Freeze import setup, Executable
27 |
28 | # Dependencies are automatically detected, but it might need
29 | # fine tuning.
30 | buildOptions = dict(packages = [], excludes = [],
31 | include_files = ['COPYING']
32 | )
33 |
34 | import sys
35 | base = 'Win32GUI' if sys.platform=='win32' else None
36 |
37 |
38 |
39 | executables = [
40 | Executable('cn5X.py', base=base)
41 | ]
42 |
43 | setup(name='cn5X++',
44 | version = APP_VERSION_STRING,
45 | description = '5/6 axis Grbl control panel for grbl-Mega-5X',
46 | author = 'Gauthier Brière',
47 | install_requires = [
48 | 'pyqt6',
49 | 'pyserial',
50 | ],
51 | options = dict(build_exe = buildOptions),
52 | executables = executables
53 | )
54 |
--------------------------------------------------------------------------------
/compilOptions.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 |
3 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
4 | ' '
5 | ' Copyright 2018-2024 Gauthier Brière (gauthier.briere "at" gmail.com) '
6 | ' '
7 | ' This file is part of cn5X++ '
8 | ' '
9 | ' cn5X++ is free software: you can redistribute it and/or modify it '
10 | ' under the terms of the GNU General Public License as published by '
11 | ' the Free Software Foundation, either version 3 of the License, or '
12 | ' (at your option) any later version. '
13 | ' '
14 | ' cn5X++ is distributed in the hope that it will be useful, but '
15 | ' WITHOUT ANY WARRANTY; without even the implied warranty of '
16 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
17 | ' GNU General Public License for more details. '
18 | ' '
19 | ' You should have received a copy of the GNU General Public License '
20 | ' along with this program. If not, see . '
21 | ' '
22 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
23 |
24 | grblCompilOptions = {
25 | 'V': ["Variable spindle enabled"],
26 | 'N': ["Line numbers enabled"],
27 | 'M': ["Mist coolant enabled"],
28 | 'G': ["Safety door support standard"],
29 | 'C': ["CoreXY enabled"],
30 | 'P': ["Parking motion enabled"],
31 | 'Z': ["Homing force origin enabled"],
32 | 'H': ["Homing single axis enabled"],
33 | 'T': ["Two limit switches on axis enabled"],
34 | 'A': ["Allow feed rate overrides in probe cycles"],
35 | '*': ["Restore all EEPROM disabled"],
36 | '$': ["Restore EEPROM $ settings disabled"],
37 | '#': ["Restore EEPROM parameter data disabled"],
38 | 'I': ["Build info write user string disabled"],
39 | 'E': ["Force sync upon EEPROM write disabled"],
40 | 'W': ["Force sync upon work coordinate offset change disabled"],
41 | 'L': ["Homing init lock sets Grbl into an alarm state upon power up"],
42 | 'D': ["Use digital input pins"]
43 | }
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cn5X++
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Panneau de contrôle Grbl 5/6 axes avec pour but d'implémenter toutes les fonctionalités de grbl-Mega-5X...
10 | *5/6 axis Grbl control panel to implement all the grbl-Mega-5X capabilities...*
11 |
12 | | *cn5X++ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.* |
13 | | :--- |
14 |
15 |
16 | ## Prérequis :
17 | cn5X++ est basé sur Python3, python-serial, PyQt6 et Qt6-SVG.
18 | Pour installer les prérequis sur un système Linux type Debian :
19 | ```
20 | sudo apt install python3-pyqt6 libqt6svg6 pyqt6-dev-tools
21 | ```
22 | En utilisation sous Linux, l'utilisateur doit faire partie du groupe Unix dialout pour pouvoir utiliser les ports série :
23 | ```
24 | sudo adduser dialout
25 | ```
26 |
27 | Après avoir installé les prérequis, copiez l'ensemble du dépôt cn5X++ (avec tous ses sous-répertoires) sur votre ordinateur puis, "exécutez" le script principal "`cn5x.py`"
28 |
29 | ## *prerequisite :*
30 | *cn5X ++ is based on Python3, python-serial, PyQt6 and Qt6-SVG.*
31 | *To install the prerequisites on a Linux system such as Debian:*
32 | ```
33 | sudo apt install python3-pyqt6 libqt6svg6 pyqt6-dev-tools
34 | ```
35 | *When using under Linux, the user must be part of the Unix dialout group to be able to use the serial ports:*
36 | ```
37 | sudo adduser dialout
38 | ```
39 |
40 | After installing the prerequisites, copy the entire cn5X++ repository (with all its subdirectories) to your computer and then "run" the main script "`cn5x.py`"
41 |
42 | -------------
43 | cn5X++ is an open-source project and fueled by the free-time of our intrepid administrators and altruistic users. If you'd like to donate, all proceeds will be used to help fund supporting hardware and testing equipment. Thank you! [](https://www.paypal.com/donate/?business=CZZN52UPPVHCW&no_recurring=0&item_name=Grbl-Mega-5X+%26+cn5X%2B%2B+donations¤cy_code=EUR)
44 |
--------------------------------------------------------------------------------
/i18n/cn5X_locales.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
26 |
27 |
28 | fr
29 |
30 | cn5X.fr.qm
31 | i18n/flags/flag_fr.svg
32 |
33 |
34 | en
35 |
36 | cn5X.en.qm
37 | i18n/flags/flag_en.svg
38 |
39 |
40 | es
41 |
42 | cn5X.es.qm
43 | i18n/flags/flag_es.svg
44 |
45 |
46 | pt
47 |
48 | cn5X.pt.qm
49 | i18n/flags/flag_pt.svg
50 |
51 |
52 |
--------------------------------------------------------------------------------
/i18n/cn5X.pro:
--------------------------------------------------------------------------------
1 | # cn5X.pro
2 | # QT Linguist translation project
3 | #'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
4 | #' '
5 | #' Copyright 2018 Gauthier Brière (gauthier.briere "at" gmail.com) '
6 | #' '
7 | #' This file is part of cn5X++ '
8 | #' '
9 | #' cn5X++ is free software: you can redistribute it and/or modify it '
10 | #' under the terms of the GNU General Public License as published by '
11 | #' the Free Software Foundation, either version 3 of the License, or '
12 | #' (at your option) any later version. '
13 | #' '
14 | #' cn5X++ is distributed in the hope that it will be useful, but '
15 | #' WITHOUT ANY WARRANTY; without even the implied warranty of '
16 | #' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
17 | #' GNU General Public License for more details. '
18 | #' '
19 | #' You should have received a copy of the GNU General Public License '
20 | #' along with this program. If not, see . '
21 | #' '
22 | #'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
23 | # Utiliser :
24 | ## cd $HOME/src/cn5X/i18n
25 | ## pylupdate5 cn5X.pro
26 | # Pour mettre à jour les sources de traduction.
27 |
28 | SOURCES = ../cn5X.py \
29 | ../cn5X_apropos.py \
30 | ../cn5X_config.py \
31 | ../cn5X_gcodeFile.py \
32 | ../cn5X_gcodeParser.py \
33 | ../cn5X_helpProbe.py \
34 | ../cn5X_jog.py \
35 | ../cn5X_toolChange.py \
36 | ../grblCom.py \
37 | ../grblComSerial.py \
38 | ../grblConfig.py \
39 | ../grblDecode.py \
40 | ../grblG28_30_1.py \
41 | ../grblG92.py \
42 | ../grblProbe.py \
43 | ../msgbox.py \
44 | ../qweditmask.py \
45 | ../qwprogressbox.py \
46 | ../speedOverrides.py
47 |
48 | FORMS = ../mainWindow.ui
49 | ../dlgAPropos.ui \
50 | ../dlgConfig.ui \
51 | ../dlgG28_30_1.ui \
52 | ../dlgG92.ui \
53 | ../dlgHelpProbe.ui \
54 | ../dlgJog.ui \
55 | ../dlgToolChange.ui \
56 | ../qwHorloge.ui \
57 | ../qwKeyboard_ui.ui \
58 | ../qwKeyNum_ui.ui \
59 |
60 | TRANSLATIONS = cn5X.fr.ts \
61 | cn5X.en.ts
62 |
63 |
64 |
--------------------------------------------------------------------------------
/images/btnClose.svg:
--------------------------------------------------------------------------------
1 |
2 |
87 |
--------------------------------------------------------------------------------
/images/btnJogPlusX.svg:
--------------------------------------------------------------------------------
1 |
2 |
78 |
--------------------------------------------------------------------------------
/images/btnJogPlusY.svg:
--------------------------------------------------------------------------------
1 |
2 |
78 |
--------------------------------------------------------------------------------
/images/btnJogMoinsY.svg:
--------------------------------------------------------------------------------
1 |
2 |
78 |
--------------------------------------------------------------------------------
/images/btnJogMoinsC.svg:
--------------------------------------------------------------------------------
1 |
2 |
78 |
--------------------------------------------------------------------------------
/images/btnJogMoinsX.svg:
--------------------------------------------------------------------------------
1 |
2 |
79 |
--------------------------------------------------------------------------------
/images/btnJogPlusC.svg:
--------------------------------------------------------------------------------
1 |
2 |
78 |
--------------------------------------------------------------------------------
/grblComStack.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 |
3 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
4 | ' '
5 | ' Copyright 2018-2024 Gauthier Brière (gauthier.briere "at" gmail.com) '
6 | ' '
7 | ' This file is part of cn5X++ '
8 | ' '
9 | ' cn5X++ is free software: you can redistribute it and/or modify it '
10 | ' under the terms of the GNU General Public License as published by '
11 | ' the Free Software Foundation, either version 3 of the License, or '
12 | ' (at your option) any later version. '
13 | ' '
14 | ' cn5X++ is distributed in the hope that it will be useful, but '
15 | ' WITHOUT ANY WARRANTY; without even the implied warranty of '
16 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
17 | ' GNU General Public License for more details. '
18 | ' '
19 | ' You should have received a copy of the GNU General Public License '
20 | ' along with this program. If not, see . '
21 | ' '
22 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
23 |
24 | from PyQt6.QtCore import QObject, QThread, QEventLoop, pyqtSignal, pyqtSlot
25 | from cn5X_config import *
26 |
27 | class grblStack():
28 | '''
29 | Gestionnaire de file d'attente du port serie.
30 | Stocke des couples (CommandeGrbl, flag), soit en mode FiFo (addFiFo()), soit en mode LiFo (addLiFo())
31 | et les renvoie dans l'ordre choisi avec la fonction pop().
32 | '''
33 |
34 | def __init__(self):
35 | self.__data = []
36 |
37 | def isEmpty(self):
38 | return len(self.__data) == 0
39 |
40 | def count(self):
41 | return len(self.__data)
42 |
43 | def addFiFo(self, item, flag = COM_FLAG_NO_FLAG):
44 | ''' Ajoute un element en mode FiFO, l'element ajoute sera le dernier a sortir
45 | '''
46 | self.__data.append((item, flag))
47 |
48 | def addLiFo(self, item, flag = COM_FLAG_NO_FLAG):
49 | ''' Ajoute un element en mode LiFO, l'element ajoute sera le premier a sortir
50 | '''
51 | self.__data.insert(0, (item, flag))
52 |
53 | def next(self):
54 | ''' Renvoie le prochain element de la Queue sans depiler (le supprimer) ou None si la liste est vide.
55 | '''
56 | if len(self.__data) > 0:
57 | return self.__data[0]
58 | else:
59 | return None
60 |
61 | def pop(self):
62 | ''' Depile et renvoie le premier element de la liste ou None si la liste est vide.
63 | '''
64 | if len(self.__data) > 0:
65 | return self.__data.pop(0)
66 | else:
67 | return None
68 |
69 | def clear(self):
70 | ''' Vide toute la pile
71 | '''
72 | self.__data.clear()
73 |
--------------------------------------------------------------------------------
/images/btnJogMoinsZ.svg:
--------------------------------------------------------------------------------
1 |
2 |
80 |
--------------------------------------------------------------------------------
/images/btnJogPlusZ.svg:
--------------------------------------------------------------------------------
1 |
2 |
80 |
--------------------------------------------------------------------------------
/speedOverrides.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 |
3 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
4 | ' '
5 | ' Copyright 2018-2024 Gauthier Brière (gauthier.briere "at" gmail.com) '
6 | ' '
7 | ' This file is part of cn5X++ '
8 | ' '
9 | ' cn5X++ is free software: you can redistribute it and/or modify it '
10 | ' under the terms of the GNU General Public License as published by '
11 | ' the Free Software Foundation, either version 3 of the License, or '
12 | ' (at your option) any later version. '
13 | ' '
14 | ' cn5X++ is distributed in the hope that it will be useful, but '
15 | ' WITHOUT ANY WARRANTY; without even the implied warranty of '
16 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
17 | ' GNU General Public License for more details. '
18 | ' '
19 | ' You should have received a copy of the GNU General Public License '
20 | ' along with this program. If not, see . '
21 | ' '
22 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
23 |
24 | from cn5X_config import *
25 | from grblCom import grblCom
26 |
27 | def adjustFeedOverride(valeurDepart: int, valeurArrivee: int, grbl: grblCom):
28 | valeurCourante = valeurDepart
29 | while valeurCourante != valeurArrivee:
30 | if valeurCourante <= valeurArrivee - 10:
31 | grbl.realTimePush(REAL_TIME_FEED_PLUS_10, COM_FLAG_NO_OK)
32 | valeurCourante += 10
33 | elif valeurCourante < valeurArrivee:
34 | grbl.realTimePush(REAL_TIME_FEED_PLUS_1, COM_FLAG_NO_OK)
35 | valeurCourante += 1
36 | elif valeurCourante >= valeurArrivee + 10:
37 | grbl.realTimePush(REAL_TIME_FEED_MOINS_10, COM_FLAG_NO_OK)
38 | valeurCourante -= 10
39 | elif valeurCourante > valeurArrivee:
40 | grbl.realTimePush(REAL_TIME_FEED_MOINS_1, COM_FLAG_NO_OK)
41 | valeurCourante -= 1
42 |
43 |
44 | def adjustSpindleOverride(valeurDepart: int, valeurArrivee: int, grbl: grblCom):
45 | valeurCourante = valeurDepart
46 | while valeurCourante != valeurArrivee:
47 | if valeurCourante <= valeurArrivee - 10:
48 | grbl.realTimePush(REAL_TIME_SPINDLE_PLUS_10, COM_FLAG_NO_OK)
49 | valeurCourante += 10
50 | elif valeurCourante < valeurArrivee:
51 | grbl.realTimePush(REAL_TIME_SPINDLE_PLUS_1, COM_FLAG_NO_OK)
52 | valeurCourante += 1
53 | elif valeurCourante >= valeurArrivee + 10:
54 | grbl.realTimePush(REAL_TIME_SPINDLE_MOINS_10, COM_FLAG_NO_OK)
55 | valeurCourante -= 10
56 | elif valeurCourante > valeurArrivee:
57 | grbl.realTimePush(REAL_TIME_SPINDLE_MOINS_1, COM_FLAG_NO_OK)
58 | valeurCourante -= 1
59 |
60 |
--------------------------------------------------------------------------------
/images/btnJogMoinsA.svg:
--------------------------------------------------------------------------------
1 |
2 |
78 |
--------------------------------------------------------------------------------
/images/btnJogPlusA.svg:
--------------------------------------------------------------------------------
1 |
2 |
78 |
--------------------------------------------------------------------------------
/images/btnJogPlusB.svg:
--------------------------------------------------------------------------------
1 |
2 |
78 |
--------------------------------------------------------------------------------
/images/btnJogMoinsB.svg:
--------------------------------------------------------------------------------
1 |
2 |
78 |
--------------------------------------------------------------------------------
/cn5X_apropos.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 |
3 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
4 | ' '
5 | ' Copyright 2018-2024 Gauthier Brière (gauthier.briere "at" gmail.com) '
6 | ' '
7 | ' This file is part of cn5X++ '
8 | ' '
9 | ' cn5X++ is free software: you can redistribute it and/or modify it '
10 | ' under the terms of the GNU General Public License as published by '
11 | ' the Free Software Foundation, either version 3 of the License, or '
12 | ' (at your option) any later version. '
13 | ' '
14 | ' cn5X++ is distributed in the hope that it will be useful, but '
15 | ' WITHOUT ANY WARRANTY; without even the implied warranty of '
16 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
17 | ' GNU General Public License for more details. '
18 | ' '
19 | ' You should have received a copy of the GNU General Public License '
20 | ' along with this program. If not, see . '
21 | ' '
22 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
23 |
24 | import os
25 | from PyQt6 import QtCore, QtGui, QtWidgets, uic
26 | from PyQt6.QtCore import Qt, QObject, pyqtSignal, pyqtSlot
27 | from PyQt6.QtWidgets import QDialog, QAbstractButton, QDialogButtonBox, QCheckBox, QSpinBox, QDoubleSpinBox, QLineEdit
28 | from PyQt6.QtGui import QStandardItemModel, QStandardItem, QValidator
29 | from cn5X_config import *
30 | from grblCom import grblCom
31 | from msgbox import *
32 |
33 |
34 | class cn5XAPropos(QDialog):
35 | ''' Classe assurant la gestion de la boite de dialogue A Propos '''
36 |
37 | def __init__(self, versionString: str, licenceFile: str):
38 | super().__init__()
39 | self.__di = uic.loadUi(os.path.join(os.path.dirname(__file__), "dlgAPropos.ui"), self)
40 |
41 | self.__di.lblVersion.setText(versionString + '\t' + "(Qt version " + QtCore.PYQT_VERSION_STR + ")")
42 |
43 | text=open(licenceFile).read()
44 | self.__di.qptLicence.setPlainText(text)
45 |
46 | def showDialog(self):
47 | # Centrage de la boite de dialogue sur la fenetre principale
48 | ParentX = self.parent().geometry().x()
49 | ParentY = self.parent().geometry().y()
50 | ParentWidth = self.parent().geometry().width()
51 | ParentHeight = self.parent().geometry().height()
52 | myWidth = self.geometry().width()
53 | myHeight = self.geometry().height()
54 | self.setFixedSize(self.geometry().width(),self.geometry().height())
55 | self.move(ParentX + int((ParentWidth - myWidth) / 2),ParentY + int((ParentHeight - myHeight) / 2),)
56 | self.setWindowFlags(Qt.WindowType.Window | Qt.WindowType.Dialog)
57 |
58 | RC = self.exec()
59 | return RC
60 |
61 |
--------------------------------------------------------------------------------
/images/btnResetSpeed.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
70 |
--------------------------------------------------------------------------------
/images/btnProbeInX-.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
98 |
--------------------------------------------------------------------------------
/images/btnProbeInX+.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
98 |
--------------------------------------------------------------------------------
/images/btnProbeOutX-.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
98 |
--------------------------------------------------------------------------------
/images/btnProbeInY-.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
98 |
--------------------------------------------------------------------------------
/images/btnProbeInY+.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
98 |
--------------------------------------------------------------------------------
/images/btnProbeOutX+.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
98 |
--------------------------------------------------------------------------------
/images/btnProbeOutY-.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
98 |
--------------------------------------------------------------------------------
/images/btnProbeOutY+.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
98 |
--------------------------------------------------------------------------------
/images/chkBoxDisabledUnChecked.svg:
--------------------------------------------------------------------------------
1 |
2 |
104 |
--------------------------------------------------------------------------------
/grblJog.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 |
3 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
4 | ' '
5 | ' Copyright 2018-2024 Gauthier Brière (gauthier.briere "at" gmail.com) '
6 | ' '
7 | ' This file is part of cn5X++ '
8 | ' '
9 | ' cn5X++ is free software: you can redistribute it and/or modify it '
10 | ' under the terms of the GNU General Public License as published by '
11 | ' the Free Software Foundation, either version 3 of the License, or '
12 | ' (at your option) any later version. '
13 | ' '
14 | ' cn5X++ is distributed in the hope that it will be useful, but '
15 | ' WITHOUT ANY WARRANTY; without even the implied warranty of '
16 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
17 | ' GNU General Public License for more details. '
18 | ' '
19 | ' You should have received a copy of the GNU General Public License '
20 | ' along with this program. If not, see . '
21 | ' '
22 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
23 |
24 | import sys, os, time #, datetime
25 | from PyQt6 import QtGui # QtCore, , QtWidgets
26 | from PyQt6.QtCore import QCoreApplication, QObject, QThread, QTimer, QEventLoop, pyqtSignal, pyqtSlot, QIODevice
27 | from cn5X_config import *
28 | from cnQPushButton import cnQPushButton
29 | from grblCom import grblCom
30 |
31 | class grblJog():
32 | '''
33 | Envoie les ordres de mouvements de Jogging
34 | A jog command will only be accepted when Grbl is in either the 'Idle' or 'Jog' states.
35 | '''
36 | def __init__(self, comm: grblCom):
37 | super().__init__()
38 | self.__grblCom = comm
39 | self.__jogSpeed = DEFAULT_JOG_SPEED
40 |
41 |
42 | @pyqtSlot(cnQPushButton, QtGui.QMouseEvent, float)
43 | @pyqtSlot(cnQPushButton, QtGui.QMouseEvent, float, float)
44 | def on_jog(self, cnButton, e, jogDistance, maxTravel=0):
45 | '''
46 | Deplacement relatif (G91) de "jogDistance" mm (G21) sur axe defini par le nom du bouton
47 | si jogDistance != 0, si jogDistance = 0, déplacement en coordonnées machine jusqu'à
48 | la course maxi.
49 | '''
50 | axis = cnButton.name()[-1] # L'axe est definit par le dernier caractere du nom du Bouton
51 |
52 | if jogDistance != 0:
53 | if cnButton.name()[-5:-1] == "Plus":
54 | value = jogDistance
55 | else:
56 | value = -jogDistance
57 | if self.__grblCom.grblStatus() in ['Idle', 'Jog']:
58 | cmdJog = CMD_GRBL_JOG + "G91G21F{}{}{}".format(self.__jogSpeed, axis, value)
59 | self.__grblCom.gcodePush(cmdJog, COM_FLAG_NO_OK)
60 |
61 | elif maxTravel != 0: # jogDistance == 0 & maxTravel !=0
62 | if cnButton.name()[-5:-1] == "Plus":
63 | value = 0
64 | else:
65 | value = -maxTravel
66 | if self.__grblCom.grblStatus() in ['Idle', 'Jog']:
67 | cmdJog = CMD_GRBL_JOG + "G53F{}{}{}".format(self.__jogSpeed, axis, value)
68 | self.__grblCom.gcodePush(cmdJog, COM_FLAG_NO_OK)
69 |
70 |
71 | def jogCancel(self):
72 | self.__grblCom.clearCom()
73 | self.__grblCom.realTimePush(REAL_TIME_JOG_CANCEL) # Commande realtime Jog Cancel
74 |
75 |
76 | def setJogSpeed(self, speed: float):
77 | if speed > 0:
78 | self.__jogSpeed = speed
79 | else:
80 | self.__jogSpeed = DEFAULT_JOG_SPEED
81 |
82 |
--------------------------------------------------------------------------------
/images/chkBoxUnChecked.svg:
--------------------------------------------------------------------------------
1 |
2 |
105 |
--------------------------------------------------------------------------------
/qwHorloge.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | qwHorloge
4 |
5 |
6 |
7 | 0
8 | 0
9 | 411
10 | 101
11 |
12 |
13 |
14 |
15 |
16 | 0
17 | 0
18 | 331
19 | 101
20 |
21 |
22 |
23 |
24 | DSEG14 Classic
25 | 72
26 | true
27 |
28 |
29 |
30 | color: rgb(24, 40, 24);
31 | background-color: None;
32 |
33 |
34 | ~~:~~
35 |
36 |
37 | Qt::PlainText
38 |
39 |
40 | Qt::AlignCenter
41 |
42 |
43 |
44 |
45 |
46 | 0
47 | 0
48 | 331
49 | 101
50 |
51 |
52 |
53 |
54 | DSEG14 Classic
55 | 72
56 | 50
57 | true
58 | false
59 |
60 |
61 |
62 | color: rgb(127, 255, 127);
63 | background-color: None;
64 |
65 |
66 | 23:59
67 |
68 |
69 | Qt::PlainText
70 |
71 |
72 | Qt::AlignCenter
73 |
74 |
75 |
76 |
77 |
78 | 330
79 | 47
80 | 81
81 | 55
82 |
83 |
84 |
85 |
86 | DSEG14 Classic
87 | 36
88 | true
89 |
90 |
91 |
92 | color: rgb(24, 40, 24);
93 | background-color: None;
94 |
95 |
96 | ~~
97 |
98 |
99 | Qt::PlainText
100 |
101 |
102 | Qt::AlignCenter
103 |
104 |
105 |
106 |
107 |
108 | 330
109 | 47
110 | 81
111 | 55
112 |
113 |
114 |
115 |
116 | DSEG14 Classic Mini
117 | 36
118 | true
119 |
120 |
121 |
122 | color: rgb(127, 255, 127);
123 | background-color: None;
124 |
125 |
126 | 59
127 |
128 |
129 | Qt::PlainText
130 |
131 |
132 | Qt::AlignCenter
133 |
134 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/cnled.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 |
3 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
4 | ' '
5 | ' Copyright 2018-2024 Gauthier Brière (gauthier.briere "at" gmail.com) '
6 | ' '
7 | ' This file is part of cn5X++ '
8 | ' '
9 | ' cn5X++ is free software: you can redistribute it and/or modify it '
10 | ' under the terms of the GNU General Public License as published by '
11 | ' the Free Software Foundation, either version 3 of the License, or '
12 | ' (at your option) any later version. '
13 | ' '
14 | ' cn5X++ is distributed in the hope that it will be useful, but '
15 | ' WITHOUT ANY WARRANTY; without even the implied warranty of '
16 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
17 | ' GNU General Public License for more details. '
18 | ' '
19 | ' You should have received a copy of the GNU General Public License '
20 | ' along with this program. If not, see . '
21 | ' '
22 | '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
23 |
24 | import sys, os
25 | from PyQt6 import QtCore, QtGui, QtWidgets
26 | from PyQt6.QtCore import pyqtSignal, pyqtSlot, QSize, pyqtProperty
27 |
28 | class cnLed(QtWidgets.QLabel):
29 | ''' QLabel affichant une image de Led eteinte ou allumee '''
30 |
31 | statusChanged = pyqtSignal(bool) # signal emis a chaque changement de valeur
32 |
33 | def __init__(self, parent=None):
34 | super(cnLed, self).__init__(parent=parent)
35 |
36 | self.__couleur = "Rouge" # Rouge ou Verte
37 |
38 | # Chemin des images dans le fichier de resources
39 | self.__imagePath = os.path.join(os.path.dirname(__file__), "images/")
40 | self.iconOff = QtGui.QPixmap(self.__imagePath + "led" + self.__couleur + "Eteinte.svg")
41 | self.iconOn = QtGui.QPixmap(self.__imagePath + "led" + self.__couleur + "Alumee.svg")
42 |
43 | # Proprietes du label
44 | self.setMaximumSize(QSize(20, 20))
45 | self.setText("")
46 | self.setPixmap(self.iconOff)
47 | self.setScaledContents(True)
48 |
49 | self.__ledStatus = False # led eteinte a l'initialisation
50 |
51 |
52 | @pyqtSlot()
53 | def Couleur(self):
54 | return self.__couleur
55 |
56 |
57 | @pyqtSlot()
58 | def setCouleur(self, couleur):
59 | if self.__couleur != couleur:
60 | self.__couleur = couleur
61 | self.iconOff = QtGui.QPixmap(self.__imagePath + "led" + self.__couleur + "Eteinte.svg")
62 | self.iconOn = QtGui.QPixmap(self.__imagePath + "led" + self.__couleur + "Alumee.svg")
63 | if self.__ledStatus:
64 | self.setPixmap(self.iconOn)
65 | else:
66 | self.setPixmap(self.iconOff)
67 |
68 |
69 | @pyqtSlot()
70 | def ledStatus(self):
71 | ''' Renvoie le status de la Led '''
72 | return self.__ledStatus
73 |
74 |
75 | @pyqtSlot(bool)
76 | def setLedStatus(self, s: bool):
77 | ''' Allume (s=True) ou eteind (s=False) la Led '''
78 | if self.__ledStatus != s:
79 | if s:
80 | self.setPixmap(self.iconOn)
81 | else:
82 | self.setPixmap(self.iconOff)
83 | self.__ledStatus = s
84 | self.statusChanged.emit(s)
85 |
86 |
87 | # Definie les propriétés pour permettre la configuration par Designer
88 | ledStatus = pyqtProperty("bool", fget=ledStatus, fset=setLedStatus)
89 | Couleur = pyqtProperty("QString", fget=Couleur, fset=setCouleur)
90 |
--------------------------------------------------------------------------------
/images/btnProbeOutCercle.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
99 |
--------------------------------------------------------------------------------
/images/btnProbeZ-.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
102 |
--------------------------------------------------------------------------------
/images/btnJogX.svg:
--------------------------------------------------------------------------------
1 |
2 |
94 |
--------------------------------------------------------------------------------
/images/btnJogY.svg:
--------------------------------------------------------------------------------
1 |
2 |
94 |
--------------------------------------------------------------------------------
/images/btnKillAlarm.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
101 |
--------------------------------------------------------------------------------
/images/btnJogZ.svg:
--------------------------------------------------------------------------------
1 |
2 |
98 |
--------------------------------------------------------------------------------
/images/btnProbeInCercle.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
108 |
--------------------------------------------------------------------------------
/images/btnJogC.svg:
--------------------------------------------------------------------------------
1 |
2 |
94 |
--------------------------------------------------------------------------------
/images/chkBoxDisabledChecked.svg:
--------------------------------------------------------------------------------
1 |
2 |
110 |
--------------------------------------------------------------------------------
/images/btnRefresh.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
82 |
--------------------------------------------------------------------------------
/images/btnJogB.svg:
--------------------------------------------------------------------------------
1 |
2 |
94 |
--------------------------------------------------------------------------------
/images/ledBleuEteinte.svg:
--------------------------------------------------------------------------------
1 |
2 |
127 |
--------------------------------------------------------------------------------
/images/btnJogA.svg:
--------------------------------------------------------------------------------
1 |
2 |
94 |
--------------------------------------------------------------------------------
/images/ledVerteEteinte.svg:
--------------------------------------------------------------------------------
1 |
2 |
127 |
--------------------------------------------------------------------------------
/images/chkBoxChecked.svg:
--------------------------------------------------------------------------------
1 |
2 |
111 |
--------------------------------------------------------------------------------
/images/ledBleuAlumee.svg:
--------------------------------------------------------------------------------
1 |
2 |
127 |
--------------------------------------------------------------------------------
/images/ledRougeEteinte.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
128 |
--------------------------------------------------------------------------------
/images/ledVerteAlumee.svg:
--------------------------------------------------------------------------------
1 |
2 |
127 |
--------------------------------------------------------------------------------
/images/btnG28.svg:
--------------------------------------------------------------------------------
1 |
2 |
105 |
--------------------------------------------------------------------------------