Skip to content

Commit 818a7e7

Browse files
author
Gauthier
committed
Validateur : Gauthier <[email protected]>
Sur la branche master Votre branche est à jour avec 'origin/master'. Modifications qui seront validées : modifié : cn5X.geany modifié : cn5X.py nouveau fichier : cnQPushButton.py modifié : gcodeQLineEdit.py modifié : gcodeQLineEditplugin.py modifié : grblAlarm.py modifié : grblCommunicator.py nouveau fichier : grblCommunicator_serial.py nouveau fichier : grblCommunicator_timer.py modifié : grblDecode.py nouveau fichier : images/btnFloodM7.svg nouveau fichier : images/btnFloodM7_down.svg nouveau fichier : images/btnFloodM7_light.svg renommé : images/btnFlood.svg -> images/btnFloodM8.svg renommé : images/btnArrosageDown.svg -> images/btnFloodM8_down.svg nouveau fichier : images/btnFloodM8_light.svg renommé : images/btnFloodOff.svg -> images/btnFloodM9.svg renommé : images/btnArrosageLight.svg -> images/btnFloodM9_down.svg nouveau fichier : images/btnFloodM9_light.svg renommé : images/btnSpindleCW.svg -> images/btnSpinM3.svg renommé : images/btnStartDown.svg -> images/btnSpinM3_down.svg nouveau fichier : images/btnSpinM3_light.svg renommé : images/btnSpindleCCW.svg -> images/btnSpinM4.svg nouveau fichier : images/btnSpinM4_down.svg nouveau fichier : images/btnSpinM4_light.svg renommé : images/btnSpindleOff.svg -> images/btnSpinM5.svg nouveau fichier : images/btnSpinM5_down.svg nouveau fichier : images/btnSpinM5_light.svg nouveau fichier : images/btnStart_down.svg renommé : images/btnStartLight.svg -> images/btnStart_light.svg renommé : images/btnStopLight.svg -> images/btnStop_down.svg renommé : images/btnStopDown.svg -> images/btnStop_light.svg modifié : mainWindow.py modifié : mainWindow.ui
1 parent 3680a20 commit 818a7e7

34 files changed

+3373
-1328
lines changed

cn5X.geany

+8-7
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,17 @@ long_line_column=72
2929

3030
[files]
3131
current_page=3
32-
FILE_NAME_0=3744;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2Fcn5X.py;0;2
32+
FILE_NAME_0=11453;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2Fcn5X.py;0;2
3333
FILE_NAME_1=0;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgrblAlarm.py;0;2
34-
FILE_NAME_2=10356;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgrblCommunicator.py;0;2
35-
FILE_NAME_3=4433;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgrblDecode.py;0;2
34+
FILE_NAME_2=7404;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgrblCommunicator.py;0;2
35+
FILE_NAME_3=14135;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgrblDecode.py;0;2
3636
FILE_NAME_4=0;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgrblError.py;0;2
37-
FILE_NAME_5=38;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgrblSettings.py;0;2
37+
FILE_NAME_5=0;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgrblSettings.py;0;2
3838
FILE_NAME_6=0;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2Fmsgbox.py;0;2
39-
FILE_NAME_7=161;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgcodeQLineEdit.py;0;2
40-
FILE_NAME_8=22;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgcodeQLineEditplugin.py;0;2
41-
FILE_NAME_9=63459;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FmainWindow.py;0;2
39+
FILE_NAME_7=0;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgcodeQLineEdit.py;0;2
40+
FILE_NAME_8=0;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FcnQPushButton.py;0;2
41+
FILE_NAME_9=0;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgrblCommunicator_serial.py;0;2
42+
FILE_NAME_10=0;Python;0;EUTF-8;0;1;0;%2Fhome%2Fgauthier%2Fsrc%2Fcn5X%2FgrblCommunicator_timer.py;0;2
4243

4344
[VTE]
4445
last_dir=/home/gauthier

cn5X.py

+111-43
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ def __init__(self, parent=None):
4242
self.__grblCom.sig_data_debug.connect(self.on_communicator_debug) # Tous les messages de Grbl
4343

4444
self.__connectionStatus = False
45+
self.__arretUrgence = True
4546

4647
pathname = os.path.abspath(os.path.dirname(sys.argv[0]))
47-
print(pathname)
4848
os.chdir(pathname)
4949

5050
"""---------- Préparation de l'interface ----------"""
@@ -64,8 +64,11 @@ def __init__(self, parent=None):
6464
# on affiche une chaine vide texte en bas de la fenêtre (status bar)
6565
self.ui.statusBar.showMessage("")
6666

67+
# Positionne l'état d'activation des contrôles
68+
self.setEnableDisableGroupes()
69+
6770
"""---------- Connections des évennements traités ----------"""
68-
self.ui.btnUrgence.pressed.connect(self.arretUrgence) # Evenements du bouton d'arrêt d'urgence
71+
self.ui.btnUrgence.pressed.connect(self.on_arretUrgence) # Evenements du bouton d'arrêt d'urgence
6972
self.ui.cmbPort.currentIndexChanged.connect(self.on_cmbPort_changed) # un clic sur un élément de la liste appellera la méthode 'on_cmbPort_changed'
7073
self.ui.mnuAppOuvrir.triggered.connect(self.on_mnuAppOuvrir) # Connexions des routines du menu application
7174
self.ui.mnuAppQuitter.triggered.connect(self.on_mnuAppQuitter)
@@ -80,6 +83,9 @@ def __init__(self, parent=None):
8083
self.ui.btnStartTimer.clicked.connect(self.startTimer)
8184
self.ui.btnStopTimer.clicked.connect(self.stopTimer)
8285
self.ui.btnClearDebug.clicked.connect(self.clearDebug)
86+
self.ui.btnFloodM7.clicked.connect(self.on_btnFloodM7)
87+
self.ui.btnFloodM8.clicked.connect(self.on_btnFloodM8)
88+
self.ui.btnFloodM9.clicked.connect(self.on_btnFloodM9)
8389

8490
def populatePortList(self):
8591
''' Rempli la liste des ports série '''
@@ -102,18 +108,58 @@ def populatePortList(self):
102108
if len(QSerialPortInfo.availablePorts()) == 1:
103109
self.ui.cmbPort.setCurrentIndex(1)
104110

105-
self.setConnectControlsStatus()
111+
self.setEnableDisableConnectControls()
106112

107-
def setConnectControlsStatus(self):
113+
def setEnableDisableConnectControls(self):
108114
'''
109-
Active ou désactive les contrôles de connexion en fonction de l'état de sélection du port
115+
Active ou désactive les contrôles de connexion en fonction de
116+
l'état de connection et de sélection du port
110117
'''
111-
if self.ui.cmbPort.currentText() == "":
118+
if self.__connectionStatus:
119+
self.ui.cmbPort.setEnabled(False)
112120
self.ui.cmbBauds.setEnabled(False)
113-
self.ui.btnConnect.setEnabled(False)
114-
else:
115-
self.ui.cmbBauds.setEnabled(True)
116121
self.ui.btnConnect.setEnabled(True)
122+
else:
123+
self.ui.cmbPort.setEnabled(True)
124+
if self.ui.cmbPort.currentText() == "":
125+
self.ui.cmbBauds.setEnabled(False)
126+
self.ui.btnConnect.setEnabled(False)
127+
else:
128+
self.ui.cmbBauds.setEnabled(True)
129+
self.ui.btnConnect.setEnabled(True)
130+
131+
def setEnableDisableGroupes(self):
132+
'''
133+
Détermine l'état Enable/Disable des différents groupes de contrôles
134+
en fonction de l'état de connexion et de l'état du bouton d'arrêt d'urgence.
135+
'''
136+
if not self.__connectionStatus:
137+
# Pas connecté, tout doit être désactivé et l'arrêt d'urgence enfoncé
138+
self.ui.btnUrgence.setIcon(QtGui.QIcon('images/btnUrgenceOff.svg'))
139+
self.ui.btnUrgence.setToolTip("Double clic pour\ndévérouiller l'arrêt d'urgence")
140+
self.ui.frmArretUrgence.setEnabled(False)
141+
self.ui.frmControleVitesse.setEnabled(False)
142+
self.ui.grpJog.setEnabled(False)
143+
self.ui.frmGcodeInput.setEnabled(False)
144+
self.ui.frmBoutons.setEnabled(False)
145+
elif self.__arretUrgence:
146+
# Connecté mais sous arrêt d'urgence : Tout est désactivé sauf l'arrêt d'urgence
147+
self.ui.btnUrgence.setIcon(QtGui.QIcon('images/btnUrgenceOff.svg'))
148+
self.ui.btnUrgence.setToolTip("Double clic pour\ndévérouiller l'arrêt d'urgence")
149+
self.ui.frmArretUrgence.setEnabled(True)
150+
self.ui.frmControleVitesse.setEnabled(False)
151+
self.ui.grpJog.setEnabled(False)
152+
self.ui.frmGcodeInput.setEnabled(False)
153+
self.ui.frmBoutons.setEnabled(False)
154+
else:
155+
# Tout est en ordre, on active tout
156+
self.ui.btnUrgence.setIcon(QtGui.QIcon('images/btnUrgence.svg'))
157+
self.ui.btnUrgence.setToolTip("Arrêt d'urgence")
158+
self.ui.frmArretUrgence.setEnabled(True)
159+
self.ui.frmControleVitesse.setEnabled(True)
160+
self.ui.grpJog.setEnabled(True)
161+
self.ui.frmGcodeInput.setEnabled(True)
162+
self.ui.frmBoutons.setEnabled(True)
117163

118164
@pyqtSlot()
119165
def on_mnuAppOuvrir(self):
@@ -133,72 +179,94 @@ def closeEvent(self, event):
133179
event.accept() # let the window close
134180

135181
def on_mnu_MPos(self, check):
136-
print("Le menu est : ", check)
182+
if check:
183+
param10 = 255 # Le bit 1 est à 1
184+
self.__grblCom.sendLine("$10=" + str(param10))
137185
pass
138186

139187
def on_mnu_WPos(self, check):
140-
print("Le menu est : ", check)
188+
if check:
189+
param10 = 255 ^ 1 # Met le bit 1 à 0
190+
self.__grblCom.sendLine("$10=" + str(param10))
141191
pass
142192

143-
def arretUrgence(self):
144-
print("Arrêt d'urgence détecté !")
145-
if not(self.ui.btnUrgence.isChecked()):
146-
print("STOP !!!")
147-
self.ui.btnUrgence.setIcon(QtGui.QIcon('images/btnUrgenceOff.svg'))
148-
self.ui.btnStart.setEnabled(False)
149-
self.ui.btnStop.setEnabled(False)
150-
self.ui.btnUrgence.setToolTip("Double clic pour\ndévérouiller l'arrêt d'urgence")
151-
else:
193+
def on_arretUrgence(self):
194+
if self.__arretUrgence:
195+
# L'arrêt d'urgence est actif, on doit faire un double click pour le désactiver
152196
if not self.timerDblClic.isActive():
153197
# On est pas dans le timer du double click,
154-
# c'est donc un simple click qui ne suffit pas à déverrouiller le bouton d'arrêt d'urgence.
198+
# c'est donc un simple click qui ne suffit pas à déverrouiller le bouton d'arrêt d'urgence,
199+
# C'est le premier click, On active le timer pour voir le le 2ème sera dans le temp imparti
155200
self.timerDblClic.setSingleShot(True)
156201
self.timerDblClic.start(QtWidgets.QApplication.instance().doubleClickInterval())
157-
self.ui.btnUrgence.setChecked(False)
158202
else:
159-
print("Double click détecté,")
160-
print(self.timerDblClic.remainingTime()) # Double clic détecté
203+
# self.timerDblClic.remainingTime() > 0 # Double clic détecté
161204
self.timerDblClic.stop()
162-
print("On relance :-)")
163-
self.ui.btnUrgence.setIcon(QtGui.QIcon('images/btnUrgence.svg'))
164-
self.ui.btnStart.setEnabled(True)
165-
self.ui.btnStop.setEnabled(True)
166-
self.ui.btnUrgence.setToolTip("Arrêt d'urgence")
205+
self.__arretUrgence = False
206+
else:
207+
self.__grblCom.sendData(chr(0x18)) # Envoi direct Ctrl+X.
208+
self.__arretUrgence = True
209+
print("Arrêt d'urgence STOP !!!")
210+
211+
# Actualise l'état actif/inactif des groupes de contrôles de pilotage de Grbl
212+
self.setEnableDisableGroupes()
167213

168214
def action_btnConnect(self):
169215
if self.ui.btnConnect.text() == "Connecter":
170-
print('Appui bouton Connecter.')
171216
# Recupère les coordonnées et paramètres du port à connecter
172217
serialDevice = self.ui.cmbPort.currentText()
173218
serialDevice = serialDevice.split("-")
174219
serialDevice = serialDevice[0].strip()
175220
baudRate = int(self.ui.cmbBauds.currentText())
176-
print("Démarrage du communicator")
221+
# Démarrage du communicator
177222
self.__grblCom.startCommunicator(serialDevice, baudRate)
178-
self.__connectionStatus = True
179-
223+
# Mise à jour de l'interface
180224
self.ui.lblConnectStatus.setText("Connecté à " + serialDevice)
181-
self.ui.cmbPort.setEnabled(False)
182-
self.ui.cmbBauds.setEnabled(False)
183225
self.ui.btnConnect.setText("Déconnecter") # La prochaine action du bouton sera pour déconnecter
226+
self.setEnableDisableConnectControls()
227+
self.__connectionStatus = True
228+
# Active les groupes de contrôles de pilotage de Grbl
229+
self.setEnableDisableGroupes()
230+
184231
else:
185-
print('Appui bouton Déconnecter.')
232+
# Arret du comunicator
186233
self.__grblCom.stopCommunicator()
187234
self.__connectionStatus = False
188-
189-
self.ui.statusBar.showMessage("")
235+
# Mise à jour de l'interface
190236
self.ui.lblConnectStatus.setText("<Non Connecté>")
191-
self.ui.cmbPort.setEnabled(True)
192-
self.ui.cmbBauds.setEnabled(True)
193237
self.ui.btnConnect.setText("Connecter") # La prochaine action du bouton sera pour connecter
238+
self.ui.statusBar.showMessage("")
239+
self.setEnableDisableConnectControls()
240+
# Force la position de l'arrêt d'urgence
241+
self.__arretUrgence = True
242+
# Active les groupes de contrôles de pilotage de Grbl
243+
self.setEnableDisableGroupes()
194244

195245
def on_cmbPort_changed(self):
196-
self.setConnectControlsStatus()
246+
self.setEnableDisableConnectControls()
247+
248+
def on_btnFloodM7(self):
249+
if self.decode.get_etatArrosage() != "M7" and self.decode.get_etatArrosage() != "M78":
250+
# Envoi "Real Time Command" plutôt que self.__grblCom.enQueue("M7")
251+
self.__grblCom.sendData(chr(0xA1))
252+
253+
def on_btnFloodM8(self):
254+
if self.decode.get_etatArrosage() != "M8" and self.decode.get_etatArrosage() != "M78":
255+
# Envoi "Real Time Command" plutôt que self.__grblCom.enQueue("M8")
256+
self.__grblCom.sendData(chr(0xA0))
257+
258+
def on_btnFloodM9(self):
259+
if self.decode.get_etatArrosage() == "M7" or self.decode.get_etatArrosage() == "M78":
260+
# Envoi "Real Time Command"
261+
self.__grblCom.sendData(chr(0xA1))
262+
if self.decode.get_etatArrosage() == "M8" or self.decode.get_etatArrosage() == "M78":
263+
# Envoi "Real Time Command" plutôt que self.__grblCom.enQueue("M9")
264+
self.__grblCom.sendData(chr(0xA0))
197265

198266
def sendCmd(self):
199267
if self.ui.txtGCode.text() != "":
200268
self.logGrbl.append(self.ui.txtGCode.text().upper())
201-
self.__grblCom.sendLine(self.ui.txtGCode.text())
269+
self.__grblCom.enQueue(self.ui.txtGCode.text())
202270
self.ui.txtGCode.setSelection(0,len(self.ui.txtGCode.text()))
203271
self.ui.txtGCode.setFocus()
204272

@@ -248,7 +316,7 @@ def on_communicator_status(self, data: str):
248316
def on_communicator_data(self, data: str):
249317
retour = self.decode.decodeGrblData(data)
250318
if retour is not None and retour != "":
251-
self.logGrbl.append(">" + retour)
319+
self.logGrbl.append(retour)
252320

253321
@pyqtSlot(str)
254322
def on_communicator_debug(self, data: str):

cnQPushButton.py

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# -*- coding: UTF-8 -*-
2+
3+
import sys, os
4+
from PyQt5 import QtCore, QtGui, QtWidgets
5+
from pathlib import Path
6+
7+
class cnQPushButton(QtWidgets.QPushButton):
8+
'''
9+
QPushButton avec gestion d'images en fonction de l'état
10+
'''
11+
12+
keyPressed = QtCore.pyqtSignal(QtGui.QKeyEvent)
13+
mousePress = QtCore.pyqtSignal(QtGui.QMouseEvent)
14+
mouseRelease = QtCore.pyqtSignal(QtGui.QMouseEvent)
15+
mouseDoubleClick = QtCore.pyqtSignal(QtGui.QMouseEvent)
16+
17+
def __init__(self, parent=None):
18+
super(cnQPushButton, self).__init__(parent=parent)
19+
self.installEventFilter(self)
20+
21+
self.__mouseIsDown = False
22+
23+
# Chemin des images
24+
appPath = os.path.abspath(os.path.dirname(sys.argv[0]))
25+
self.__imagePath = appPath + "/images/"
26+
self.__buttonStatus = False
27+
28+
self.icon = QtGui.QIcon()
29+
self.iconDown = QtGui.QIcon()
30+
self.iconLight = QtGui.QIcon()
31+
32+
def eventFilter(self, object, event):
33+
if event.type() == QtCore.QEvent.DynamicPropertyChange:
34+
pictureBaseName = self.__imagePath + object.objectName()
35+
36+
f = Path(pictureBaseName + ".svg")
37+
if f.is_file():
38+
self.icon.addPixmap(QtGui.QPixmap(pictureBaseName + ".svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
39+
else:
40+
print ("Image du bouton {} non trouvée.".format(pictureBaseName + ".svg"))
41+
42+
f = Path(pictureBaseName + "_down.svg")
43+
if f.is_file():
44+
self.iconDown.addPixmap(QtGui.QPixmap(pictureBaseName + "_down.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
45+
else:
46+
print ("Image du bouton {} non trouvée.".format(pictureBaseName + "_down.svg"))
47+
48+
f = Path(pictureBaseName + "_light.svg")
49+
if f.is_file():
50+
self.iconLight.addPixmap(QtGui.QPixmap(pictureBaseName + "_light.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
51+
else:
52+
print ("Image du bouton {} non trouvée.".format(pictureBaseName + "_light.svg"))
53+
54+
return False
55+
56+
def mousePressEvent(self, e):
57+
self.__mouseIsDown = True
58+
super(cnQPushButton, self).mousePressEvent(e)
59+
self.setIcon(self.iconDown)
60+
self.mousePress.emit(e)
61+
62+
def mouseReleaseEvent(self, e):
63+
self.__mouseIsDown = False
64+
super(cnQPushButton, self).mouseReleaseEvent(e)
65+
self.__buttonStatus = True
66+
if self.__buttonStatus:
67+
self.setIcon(self.iconLight)
68+
else:
69+
self.setIcon(self.icon)
70+
self.mouseRelease.emit(e)
71+
72+
def setButtonStatus(self, value: bool):
73+
self.__buttonStatus = value
74+
if not self.__mouseIsDown:
75+
if self.__buttonStatus:
76+
self.setIcon(self.iconLight)
77+
else:
78+
self.setIcon(self.icon)
79+
80+
def getButtonStatus(self):
81+
return self.__buttonStatus
82+
83+
def mouseDoubleClickEvent(self, e):
84+
print("mouseDoubleClickEvent")
85+
super(cnQPushButton, self).mouseDoubleClickEvent(e)
86+
self.mouseDoubleClick.emit(e)
87+
88+
def keyPressEvent(self, e):
89+
super(cnQPushButton, self).keyPressEvent(e)
90+
self.keyPressed.emit(e)

gcodeQLineEdit.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
from PyQt5 import QtCore, QtGui, QtWidgets
44

55
class gcodeQLineEdit(QtWidgets.QLineEdit):
6-
6+
'''
7+
QlineEdit avec ajout de l'évennement KeyPressed
8+
'''
79
keyPressed = QtCore.pyqtSignal(QtGui.QKeyEvent)
810

911
def __init__(self, parent=None):

gcodeQLineEditplugin.py

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#!/usr/bin/env python
21
# -*- coding: UTF-8 -*-
32

43
from PyQt5 import QtGui, QtDesigner

grblAlarm.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python
1+
# -*- coding: UTF-8 -*-
22

33
grblAlarm = [
44
[0, "No Alarm."],

0 commit comments

Comments
 (0)