View  Edit  Attributes  History  Attach  Print  Search

PYQTLAB

PyQt Lab' : Port Série : en envoi : Envoyer sur le port série une valeur numérique saisie à l'aide d'un clavier graphique.

Par X. HINAULT - Juin 2013

Ce que l'on va faire ici

  • Dans ce code PyQt, interface graphique permettant d'envoyer sur le port série une valeur numérique saisie à l'aide d'un clavier graphique.

Pré-requis

  • python 2.7
  • pyqt4.x
  • modules :
    • python-serial

Téléchargement :

$ cd scripts_pyqt
$ mkdir tuto_pyqt_pyserial_clavier_pushbutton_envoi
$ cd tuto_pyqt_pyserial_clavier_pushbutton_envoi
$ wget -4 -N https://raw.github.com/sensor56/PyQt-Lab/master/tuto_pyqt_pyserial_clavier_pushbutton_envoi/tuto_pyqt_pyserial_clavier_pushbutton_envoi.py
$ wget -4 -N https://raw.github.com/sensor56/PyQt-Lab/master/tuto_pyqt_pyserial_clavier_pushbutton_envoi/tuto_pyqt_pyserial_clavier_pushbutton_envoiMain.py

Le fichier d'interface *.py

  • Fichier obtenu automatiquement avec l'utilitaire pyuic4 à partir du fichier *.ui créé avec QtDesigner :
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file
#
# Created: Fri Feb  8 20:48:57 2013
#      by: PyQt4 UI code generator 4.9.1
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(499, 348)
        self.pushButton_7 = QtGui.QPushButton(Form)
        self.pushButton_7.setGeometry(QtCore.QRect(195, 50, 50, 50))
        self.pushButton_7.setObjectName(_fromUtf8("pushButton_7"))
        self.pushButton_8 = QtGui.QPushButton(Form)
        self.pushButton_8.setGeometry(QtCore.QRect(250, 50, 50, 50))
        self.pushButton_8.setObjectName(_fromUtf8("pushButton_8"))
        self.pushButton_9 = QtGui.QPushButton(Form)
        self.pushButton_9.setGeometry(QtCore.QRect(305, 50, 50, 50))
        self.pushButton_9.setObjectName(_fromUtf8("pushButton_9"))
        self.pushButton_5 = QtGui.QPushButton(Form)
        self.pushButton_5.setGeometry(QtCore.QRect(250, 105, 50, 50))
        self.pushButton_5.setObjectName(_fromUtf8("pushButton_5"))
        self.pushButton_4 = QtGui.QPushButton(Form)
        self.pushButton_4.setGeometry(QtCore.QRect(195, 105, 50, 50))
        self.pushButton_4.setObjectName(_fromUtf8("pushButton_4"))
        self.pushButton_6 = QtGui.QPushButton(Form)
        self.pushButton_6.setGeometry(QtCore.QRect(305, 105, 50, 50))
        self.pushButton_6.setObjectName(_fromUtf8("pushButton_6"))
        self.pushButton_2 = QtGui.QPushButton(Form)
        self.pushButton_2.setGeometry(QtCore.QRect(250, 160, 50, 50))
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
        self.pushButton_1 = QtGui.QPushButton(Form)
        self.pushButton_1.setGeometry(QtCore.QRect(195, 160, 50, 50))
        self.pushButton_1.setObjectName(_fromUtf8("pushButton_1"))
        self.pushButton_3 = QtGui.QPushButton(Form)
        self.pushButton_3.setGeometry(QtCore.QRect(305, 160, 50, 50))
        self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
        self.lineEdit = QtGui.QLineEdit(Form)
        self.lineEdit.setGeometry(QtCore.QRect(190, 5, 171, 36))
        font = QtGui.QFont()
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        self.lineEdit.setFont(font)
        self.lineEdit.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.lineEdit.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.pushButton_0 = QtGui.QPushButton(Form)
        self.pushButton_0.setGeometry(QtCore.QRect(195, 215, 50, 50))
        self.pushButton_0.setObjectName(_fromUtf8("pushButton_0"))
        self.pushButton_Clear = QtGui.QPushButton(Form)
        self.pushButton_Clear.setGeometry(QtCore.QRect(305, 215, 50, 50))
        self.pushButton_Clear.setObjectName(_fromUtf8("pushButton_Clear"))
        self.pushButton_point = QtGui.QPushButton(Form)
        self.pushButton_point.setGeometry(QtCore.QRect(250, 215, 50, 50))
        self.pushButton_point.setObjectName(_fromUtf8("pushButton_point"))
        self.comboBoxPort = QtGui.QComboBox(Form)
        self.comboBoxPort.setGeometry(QtCore.QRect(5, 20, 121, 24))
        self.comboBoxPort.setEditable(True)
        self.comboBoxPort.setObjectName(_fromUtf8("comboBoxPort"))
        self.comboBoxPort.addItem(_fromUtf8(""))
        self.comboBoxPort.addItem(_fromUtf8(""))
        self.comboBoxPort.addItem(_fromUtf8(""))
        self.comboBoxPort.addItem(_fromUtf8(""))
        self.lineEditChaineEnvoi = QtGui.QLineEdit(Form)
        self.lineEditChaineEnvoi.setGeometry(QtCore.QRect(5, 120, 166, 23))
        self.lineEditChaineEnvoi.setObjectName(_fromUtf8("lineEditChaineEnvoi"))
        self.line_2 = QtGui.QFrame(Form)
        self.line_2.setGeometry(QtCore.QRect(5, 185, 166, 16))
        self.line_2.setFrameShape(QtGui.QFrame.HLine)
        self.line_2.setFrameShadow(QtGui.QFrame.Sunken)
        self.line_2.setObjectName(_fromUtf8("line_2"))
        self.pushButtonInitSerial = QtGui.QPushButton(Form)
        self.pushButtonInitSerial.setGeometry(QtCore.QRect(130, 10, 41, 81))
        self.pushButtonInitSerial.setObjectName(_fromUtf8("pushButtonInitSerial"))
        self.textEditReception = QtGui.QTextEdit(Form)
        self.textEditReception.setGeometry(QtCore.QRect(5, 220, 171, 121))
        self.textEditReception.setStyleSheet(_fromUtf8("background-color: rgb(244, 255, 190);"))
        self.textEditReception.setLineWrapMode(QtGui.QTextEdit.NoWrap)
        self.textEditReception.setObjectName(_fromUtf8("textEditReception"))
        self.line = QtGui.QFrame(Form)
        self.line.setGeometry(QtCore.QRect(5, 90, 166, 16))
        self.line.setFrameShape(QtGui.QFrame.HLine)
        self.line.setFrameShadow(QtGui.QFrame.Sunken)
        self.line.setObjectName(_fromUtf8("line"))
        self.labelTraceEnvoiSerie = QtGui.QLabel(Form)
        self.labelTraceEnvoiSerie.setGeometry(QtCore.QRect(195, 270, 166, 16))
        self.labelTraceEnvoiSerie.setObjectName(_fromUtf8("labelTraceEnvoiSerie"))
        self.textEditTraceEnvoiSerie = QtGui.QTextEdit(Form)
        self.textEditTraceEnvoiSerie.setGeometry(QtCore.QRect(195, 285, 166, 61))
        self.textEditTraceEnvoiSerie.setStyleSheet(_fromUtf8("color: rgb(0, 0, 255);\n"
"background-color: rgb(170, 255, 255);"))
        self.textEditTraceEnvoiSerie.setLineWrapMode(QtGui.QTextEdit.NoWrap)
        self.textEditTraceEnvoiSerie.setObjectName(_fromUtf8("textEditTraceEnvoiSerie"))
        self.comboBoxFinLigne = QtGui.QComboBox(Form)
        self.comboBoxFinLigne.setGeometry(QtCore.QRect(5, 160, 121, 24))
        self.comboBoxFinLigne.setObjectName(_fromUtf8("comboBoxFinLigne"))
        self.comboBoxFinLigne.addItem(_fromUtf8(""))
        self.comboBoxFinLigne.addItem(_fromUtf8(""))
        self.comboBoxFinLigne.addItem(_fromUtf8(""))
        self.comboBoxFinLigne.addItem(_fromUtf8(""))
        self.pushButtonEnvoi = QtGui.QPushButton(Form)
        self.pushButtonEnvoi.setGeometry(QtCore.QRect(130, 145, 41, 41))
        self.pushButtonEnvoi.setObjectName(_fromUtf8("pushButtonEnvoi"))
        self.labelFinLigne = QtGui.QLabel(Form)
        self.labelFinLigne.setGeometry(QtCore.QRect(5, 145, 71, 16))
        self.labelFinLigne.setObjectName(_fromUtf8("labelFinLigne"))
        self.labelChaineEnvoi = QtGui.QLabel(Form)
        self.labelChaineEnvoi.setGeometry(QtCore.QRect(5, 105, 121, 16))
        self.labelChaineEnvoi.setObjectName(_fromUtf8("labelChaineEnvoi"))
        self.comboBoxDebit = QtGui.QComboBox(Form)
        self.comboBoxDebit.setGeometry(QtCore.QRect(5, 65, 121, 24))
        self.comboBoxDebit.setObjectName(_fromUtf8("comboBoxDebit"))
        self.comboBoxDebit.addItem(_fromUtf8(""))
        self.comboBoxDebit.addItem(_fromUtf8(""))
        self.comboBoxDebit.addItem(_fromUtf8(""))
        self.comboBoxDebit.addItem(_fromUtf8(""))
        self.comboBoxDebit.addItem(_fromUtf8(""))
        self.comboBoxDebit.addItem(_fromUtf8(""))
        self.comboBoxDebit.addItem(_fromUtf8(""))
        self.comboBoxDebit.addItem(_fromUtf8(""))
        self.labelDebit = QtGui.QLabel(Form)
        self.labelDebit.setGeometry(QtCore.QRect(5, 50, 111, 16))
        self.labelDebit.setObjectName(_fromUtf8("labelDebit"))
        self.line_3 = QtGui.QFrame(Form)
        self.line_3.setGeometry(QtCore.QRect(180, 5, 10, 331))
        self.line_3.setFrameShape(QtGui.QFrame.VLine)
        self.line_3.setFrameShadow(QtGui.QFrame.Sunken)
        self.line_3.setObjectName(_fromUtf8("line_3"))
        self.labelReception = QtGui.QLabel(Form)
        self.labelReception.setGeometry(QtCore.QRect(5, 200, 191, 16))
        self.labelReception.setObjectName(_fromUtf8("labelReception"))
        self.labelPort = QtGui.QLabel(Form)
        self.labelPort.setGeometry(QtCore.QRect(5, 5, 101, 16))
        self.labelPort.setObjectName(_fromUtf8("labelPort"))
        self.pushButtonEnvoiValeur_1 = QtGui.QPushButton(Form)
        self.pushButtonEnvoiValeur_1.setGeometry(QtCore.QRect(375, 5, 116, 36))
        self.pushButtonEnvoiValeur_1.setObjectName(_fromUtf8("pushButtonEnvoiValeur_1"))
        self.lineEditChaineEnvoiValeur_1 = QtGui.QLineEdit(Form)
        self.lineEditChaineEnvoiValeur_1.setGeometry(QtCore.QRect(375, 40, 116, 23))
        self.lineEditChaineEnvoiValeur_1.setObjectName(_fromUtf8("lineEditChaineEnvoiValeur_1"))
        self.line_5 = QtGui.QFrame(Form)
        self.line_5.setGeometry(QtCore.QRect(360, 5, 16, 326))
        self.line_5.setFrameShape(QtGui.QFrame.VLine)
        self.line_5.setFrameShadow(QtGui.QFrame.Sunken)
        self.line_5.setObjectName(_fromUtf8("line_5"))
        self.pushButtonEnvoiValeur_2 = QtGui.QPushButton(Form)
        self.pushButtonEnvoiValeur_2.setGeometry(QtCore.QRect(375, 75, 116, 36))
        self.pushButtonEnvoiValeur_2.setObjectName(_fromUtf8("pushButtonEnvoiValeur_2"))
        self.lineEditChaineEnvoiValeur_2 = QtGui.QLineEdit(Form)
        self.lineEditChaineEnvoiValeur_2.setGeometry(QtCore.QRect(375, 110, 116, 23))
        self.lineEditChaineEnvoiValeur_2.setObjectName(_fromUtf8("lineEditChaineEnvoiValeur_2"))
        self.pushButtonEnvoiValeur_3 = QtGui.QPushButton(Form)
        self.pushButtonEnvoiValeur_3.setGeometry(QtCore.QRect(375, 145, 116, 36))
        self.pushButtonEnvoiValeur_3.setObjectName(_fromUtf8("pushButtonEnvoiValeur_3"))
        self.lineEditChaineEnvoiValeur_3 = QtGui.QLineEdit(Form)
        self.lineEditChaineEnvoiValeur_3.setGeometry(QtCore.QRect(375, 180, 116, 23))
        self.lineEditChaineEnvoiValeur_3.setObjectName(_fromUtf8("lineEditChaineEnvoiValeur_3"))
        self.pushButtonEnvoiValeur_4 = QtGui.QPushButton(Form)
        self.pushButtonEnvoiValeur_4.setGeometry(QtCore.QRect(375, 215, 116, 36))
        self.pushButtonEnvoiValeur_4.setObjectName(_fromUtf8("pushButtonEnvoiValeur_4"))
        self.lineEditChaineEnvoiValeur_4 = QtGui.QLineEdit(Form)
        self.lineEditChaineEnvoiValeur_4.setGeometry(QtCore.QRect(375, 250, 116, 23))
        self.lineEditChaineEnvoiValeur_4.setObjectName(_fromUtf8("lineEditChaineEnvoiValeur_4"))
        self.pushButtonEnvoiValeur_5 = QtGui.QPushButton(Form)
        self.pushButtonEnvoiValeur_5.setGeometry(QtCore.QRect(375, 285, 116, 36))
        self.pushButtonEnvoiValeur_5.setObjectName(_fromUtf8("pushButtonEnvoiValeur_5"))
        self.lineEditChaineEnvoiValeur_5 = QtGui.QLineEdit(Form)
        self.lineEditChaineEnvoiValeur_5.setGeometry(QtCore.QRect(375, 320, 116, 23))
        self.lineEditChaineEnvoiValeur_5.setObjectName(_fromUtf8("lineEditChaineEnvoiValeur_5"))
        self.line_4 = QtGui.QFrame(Form)
        self.line_4.setGeometry(QtCore.QRect(195, 260, 166, 16))
        self.line_4.setFrameShape(QtGui.QFrame.HLine)
        self.line_4.setFrameShadow(QtGui.QFrame.Sunken)
        self.line_4.setObjectName(_fromUtf8("line_4"))

        self.retranslateUi(Form)
        self.comboBoxFinLigne.setCurrentIndex(1)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(QtGui.QApplication.translate("Form", "Clavier + PySerial : Saisie et envoi de valeurs sur le port Série", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_7.setText(QtGui.QApplication.translate("Form", "7", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_8.setText(QtGui.QApplication.translate("Form", "8", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_9.setText(QtGui.QApplication.translate("Form", "9", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_5.setText(QtGui.QApplication.translate("Form", "5", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_4.setText(QtGui.QApplication.translate("Form", "4", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_6.setText(QtGui.QApplication.translate("Form", "6", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_2.setText(QtGui.QApplication.translate("Form", "2", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_1.setText(QtGui.QApplication.translate("Form", "1", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_3.setText(QtGui.QApplication.translate("Form", "3", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEdit.setText(QtGui.QApplication.translate("Form", "0", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_0.setText(QtGui.QApplication.translate("Form", "0", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_Clear.setText(QtGui.QApplication.translate("Form", "CE", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_point.setText(QtGui.QApplication.translate("Form", ".", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxPort.setItemText(0, QtGui.QApplication.translate("Form", "/dev/ttyACM0", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxPort.setItemText(1, QtGui.QApplication.translate("Form", "/dev/ttyACM1", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxPort.setItemText(2, QtGui.QApplication.translate("Form", "/dev/ttyUSB0", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxPort.setItemText(3, QtGui.QApplication.translate("Form", "/dev/ttyUSB1", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonInitSerial.setText(QtGui.QApplication.translate("Form", "Init", None, QtGui.QApplication.UnicodeUTF8))
        self.labelTraceEnvoiSerie.setText(QtGui.QApplication.translate("Form", "Envoi sur le port série : ", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxFinLigne.setItemText(0, QtGui.QApplication.translate("Form", "Rien", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxFinLigne.setItemText(1, QtGui.QApplication.translate("Form", "Saut de ligne (\\n = LF)", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxFinLigne.setItemText(2, QtGui.QApplication.translate("Form", "Retour Chariot (\\r = CR)", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxFinLigne.setItemText(3, QtGui.QApplication.translate("Form", "Les 2 (LF + CR)", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonEnvoi.setText(QtGui.QApplication.translate("Form", "Envoi", None, QtGui.QApplication.UnicodeUTF8))
        self.labelFinLigne.setText(QtGui.QApplication.translate("Form", "Fin de ligne :", None, QtGui.QApplication.UnicodeUTF8))
        self.labelChaineEnvoi.setText(QtGui.QApplication.translate("Form", "Chaîne à envoyer :", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxDebit.setItemText(0, QtGui.QApplication.translate("Form", "115200", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxDebit.setItemText(1, QtGui.QApplication.translate("Form", "57600", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxDebit.setItemText(2, QtGui.QApplication.translate("Form", "38400", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxDebit.setItemText(3, QtGui.QApplication.translate("Form", "28800", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxDebit.setItemText(4, QtGui.QApplication.translate("Form", "19200", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxDebit.setItemText(5, QtGui.QApplication.translate("Form", "14400", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxDebit.setItemText(6, QtGui.QApplication.translate("Form", "9600", None, QtGui.QApplication.UnicodeUTF8))
        self.comboBoxDebit.setItemText(7, QtGui.QApplication.translate("Form", "4800", None, QtGui.QApplication.UnicodeUTF8))
        self.labelDebit.setText(QtGui.QApplication.translate("Form", "Débit Série (bauds) :", None, QtGui.QApplication.UnicodeUTF8))
        self.labelReception.setText(QtGui.QApplication.translate("Form", "Réception sur le port série : ", None, QtGui.QApplication.UnicodeUTF8))
        self.labelPort.setText(QtGui.QApplication.translate("Form", "Port Série :", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonEnvoiValeur_1.setText(QtGui.QApplication.translate("Form", "Envoi", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditChaineEnvoiValeur_1.setText(QtGui.QApplication.translate("Form", "servoTo(", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonEnvoiValeur_2.setText(QtGui.QApplication.translate("Form", "Envoi", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditChaineEnvoiValeur_2.setText(QtGui.QApplication.translate("Form", "servoPanTo(", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonEnvoiValeur_3.setText(QtGui.QApplication.translate("Form", "Envoi", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditChaineEnvoiValeur_3.setText(QtGui.QApplication.translate("Form", "servoTiltTo(", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonEnvoiValeur_4.setText(QtGui.QApplication.translate("Form", "Envoi", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditChaineEnvoiValeur_4.setText(QtGui.QApplication.translate("Form", "vitesseServo(", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonEnvoiValeur_5.setText(QtGui.QApplication.translate("Form", "Envoi", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditChaineEnvoiValeur_5.setText(QtGui.QApplication.translate("Form", "vitesseServo(", None, QtGui.QApplication.UnicodeUTF8))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Form = QtGui.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

 

Le fichier d'application *Main.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

# par X. HINAULT - Janv 2013 - Tous droits réservés
# GPLv3 - www.mon-club-elec.fr

# modules a importer
from PyQt4.QtGui import *
from PyQt4.QtCore import *  # inclut QTimer..
import os,sys

import serial # communication serie

from tuto_pyqt_pyserial_clavier_pushbutton_envoi import * # fichier obtenu à partir QtDesigner et pyuic4

class myApp(QWidget, Ui_Form): # la classe reçoit le Qwidget principal ET la classe définie dans test.py obtenu avec pyuic4
        def __init__(self, parent=None):
                QWidget.__init__(self) # initialise le Qwidget principal
                self.setupUi(parent) # Obligatoire

                #Ici, personnalisez vos widgets si nécessaire

                #Réalisez les connexions supplémentaires entre signaux et slots
                # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue

                # -- les boutons du clavier numérique --
                self.connect(self.pushButton_0, SIGNAL("clicked()"), self.pushButton_0Clicked)
                self.connect(self.pushButton_1, SIGNAL("clicked()"), self.pushButton_1Clicked)
                self.connect(self.pushButton_2, SIGNAL("clicked()"), self.pushButton_2Clicked)
                self.connect(self.pushButton_3, SIGNAL("clicked()"), self.pushButton_3Clicked)
                self.connect(self.pushButton_4, SIGNAL("clicked()"), self.pushButton_4Clicked)
                self.connect(self.pushButton_5, SIGNAL("clicked()"), self.pushButton_5Clicked)
                self.connect(self.pushButton_6, SIGNAL("clicked()"), self.pushButton_6Clicked)
                self.connect(self.pushButton_7, SIGNAL("clicked()"), self.pushButton_7Clicked)
                self.connect(self.pushButton_8, SIGNAL("clicked()"), self.pushButton_8Clicked)
                self.connect(self.pushButton_9, SIGNAL("clicked()"), self.pushButton_9Clicked)
                self.connect(self.pushButton_point, SIGNAL("clicked()"), self.pushButton_pointClicked)
                self.connect(self.pushButton_Clear, SIGNAL("clicked()"), self.pushButton_ClearClicked)

                # -- les boutons du terminal série --
                self.connect(self.pushButtonInitSerial, SIGNAL("clicked()"), self.pushButtonInitSerialClicked)
                self.connect(self.pushButtonEnvoi, SIGNAL("clicked()"), self.pushButtonEnvoiClicked)

                # -- les boutons d'envoi série --
                self.connect(self.pushButtonEnvoiValeur_1, SIGNAL("clicked()"), self.pushButtonEnvoiValeur_1Clicked)           
                self.connect(self.pushButtonEnvoiValeur_2, SIGNAL("clicked()"), self.pushButtonEnvoiValeur_2Clicked)           
                self.connect(self.pushButtonEnvoiValeur_3, SIGNAL("clicked()"), self.pushButtonEnvoiValeur_3Clicked)           
                self.connect(self.pushButtonEnvoiValeur_4, SIGNAL("clicked()"), self.pushButtonEnvoiValeur_4Clicked)           
                self.connect(self.pushButtonEnvoiValeur_5, SIGNAL("clicked()"), self.pushButtonEnvoiValeur_5Clicked)           

                #-- variables utiles --
                self.flagPoint=False # témoin point déjà utilisé pour éviter 2 fois...         
                self.serialPort=None # déclaration initiale

                #initialisation Timer
                self.timer=QTimer() # déclare un timer Qt
                self.connect(self.timer, SIGNAL("timeout()"), self.timerEvent) # connecte le signal timeOut de l'objet timer à l'appel de la fonction voulue

        # les fonctions appelées, utilisées par les signaux

        #----- les fonctions des signaux des boutons du Terminal série ----                            
        def pushButtonInitSerialClicked(self): # lors appui bouton initialisation série
                print("Bouton Init cliqué")
                if self.serialPort: # si le port existe déjà
                        self.serialPort.close() # ferme le port si existe

                # -- initialise paramètres initialisation
                if self.comboBoxPort.currentText()=="" : # si le champ d'initialisation Port est vide = initialisation par défaut
                        strPortInit="/dev/ttyACM0" # port par défaut
                else :
                        strPortInit=str(self.comboBoxPort.currentText()) #sinon utilise paramètre champ texte pour le port

                strDebitInit=str(self.comboBoxDebit.currentText()) # paramètre champ texte pour debit

                #--- initialisation série avec gestion erreur ---                      
                try: # essaie d'exécuter les instructions
                        # initialise port serie avec délai attente en réception en ms
                        self.serialPort=serial.Serial(strPortInit, strDebitInit, serial.EIGHTBITS, serial.PARITY_NONE, serial.STOPBITS_ONE, 0.100)                     
                        #self.serialPort=serial.Serial(strPortInit, strDebitInit) # initialise port serie forme réduite
                        self.serialPort.flushInput() # vide la file d'attente série
                        print("Initialisation Port Série : " + strPortInit +" @ " + strDebitInit +" = OK ") # affiche debug

                        #-- change aspect bouton init
                        self.pushButtonInitSerial.setStyleSheet(QString.fromUtf8("background-color: rgb(0, 255, 0);")) # bouton en vert
                        self.pushButtonInitSerial.setText("OK")  # change titre bouton

                except: # si erreur initialisation
                        print("Erreur initialisation Série")           

                        #-- change aspect bouton init
                        self.pushButtonInitSerial.setStyleSheet(QString.fromUtf8("background-color: rgb(255, 127, 0);")) # bouton en orange
                        self.pushButtonInitSerial.setText(QString.fromUtf8("PB"))  # change titre bouton

                self.timer.start(10) # lance le timer avec délai en ms - 10 pour réception rapide

        def pushButtonEnvoiClicked(self): # lors appui bouton envoi série du champ du Terminal Série
                print("Bouton ENVOI appuyé")
                self.envoiChaineSerie(str(self.lineEditChaineEnvoi.text())) # envoi le contenu du champ texte sur le port série

        #--------- fonctions des boutons d'envoi des valeurs numériques à partir valeur clavier ---------
        def pushButtonEnvoiValeur_1Clicked(self): # lors appui bouton envoi série du champ du Terminal Série
                print("Bouton ENVOI Valeur 1 appuyé")
                if self.lineEditChaineEnvoiValeur_1.text()=="": # si champ racine vide
                        self.envoiChaineSerie(str(self.lineEdit.text())) # envoi le contenu du champ numérique seul sur le port série
                else: # sinon, = si champ racine pas vide
                        self.envoiChaineSerie(str(self.lineEditChaineEnvoiValeur_1.text())+str(self.lineEdit.text())+")") # envoi le contenu du champ racine + champ numérique + ")" sur le port série

        def pushButtonEnvoiValeur_2Clicked(self): # lors appui bouton envoi série du champ du Terminal Série
                print("Bouton ENVOI Valeur 2 appuyé")
                if self.lineEditChaineEnvoiValeur_2.text()=="": # si champ racine vide
                        self.envoiChaineSerie(str(self.lineEdit.text())) # envoi le contenu du champ numérique seul sur le port série
                else: # sinon, = si champ racine pas vide
                        self.envoiChaineSerie(str(self.lineEditChaineEnvoiValeur_2.text())+str(self.lineEdit.text())+")") # envoi le contenu du champ racine + champ numérique + ")" sur le port série

        def pushButtonEnvoiValeur_3Clicked(self): # lors appui bouton envoi série du champ du Terminal Série
                print("Bouton ENVOI Valeur 3 appuyé")
                if self.lineEditChaineEnvoiValeur_3.text()=="": # si champ racine vide
                        self.envoiChaineSerie(str(self.lineEdit.text())) # envoi le contenu du champ numérique seul sur le port série
                else: # sinon, = si champ racine pas vide
                        self.envoiChaineSerie(str(self.lineEditChaineEnvoiValeur_3.text())+str(self.lineEdit.text())+")") # envoi le contenu du champ racine + champ numérique + ")" sur le port série

        def pushButtonEnvoiValeur_4Clicked(self): # lors appui bouton envoi série du champ du Terminal Série
                print("Bouton ENVOI Valeur 4 appuyé")
                if self.lineEditChaineEnvoiValeur_4.text()=="": # si champ racine vide
                        self.envoiChaineSerie(str(self.lineEdit.text())) # envoi le contenu du champ numérique seul sur le port série
                else: # sinon, = si champ racine pas vide
                        self.envoiChaineSerie(str(self.lineEditChaineEnvoiValeur_4.text())+str(self.lineEdit.text())+")") # envoi le contenu du champ racine + champ numérique + ")" sur le port série

        def pushButtonEnvoiValeur_5Clicked(self): # lors appui bouton envoi série du champ du Terminal Série
                print("Bouton ENVOI Valeur 5 appuyé")
                if self.lineEditChaineEnvoiValeur_5.text()=="": # si champ racine vide
                        self.envoiChaineSerie(str(self.lineEdit.text())) # envoi le contenu du champ numérique seul sur le port série
                else: # sinon, = si champ racine pas vide
                        self.envoiChaineSerie(str(self.lineEditChaineEnvoiValeur_5.text())+str(self.lineEdit.text())+")") # envoi le contenu du champ racine + champ numérique + ")" sur le port série


        #-------- fonctions des boutons du clavier --------------
        def pushButton_0Clicked(self):
                print("Bouton " + str(self.pushButton_0.text())+ " cliqué")
                self.setLineEdit("0") # appelle fonction locale

        def pushButton_1Clicked(self):
                print("Bouton " + str(self.pushButton_1.text())+ " cliqué")
                self.setLineEdit("1") # appelle fonction locale

        def pushButton_2Clicked(self):
                print("Bouton " + str(self.pushButton_2.text())+ " cliqué")
                self.setLineEdit("2") # appelle fonction locale

        def pushButton_3Clicked(self):
                print("Bouton " + str(self.pushButton_3.text())+ " cliqué")
                self.setLineEdit("3") # appelle fonction locale

        def pushButton_4Clicked(self):
                print("Bouton " + str(self.pushButton_4.text())+ " cliqué")
                self.setLineEdit("4") # appelle fonction locale

        def pushButton_5Clicked(self):
                print("Bouton " + str(self.pushButton_5.text())+ " cliqué")
                self.setLineEdit("5") # appelle fonction locale

        def pushButton_6Clicked(self):
                print("Bouton " + str(self.pushButton_6.text())+ " cliqué")
                self.setLineEdit("6") # appelle fonction locale

        def pushButton_7Clicked(self):
                print("Bouton " + str(self.pushButton_7.text())+ " cliqué")
                self.setLineEdit("7") # appelle fonction locale

        def pushButton_8Clicked(self):
                print("Bouton " + str(self.pushButton_8.text())+ " cliqué")
                self.setLineEdit("8") # appelle fonction locale

        def pushButton_9Clicked(self):
                print("Bouton " + str(self.pushButton_9.text())+ " cliqué")
                self.setLineEdit("9") # appelle fonction locale

        def pushButton_pointClicked(self):
                print("Bouton " + str(self.pushButton_point.text())+ " cliqué")
                if not self.flagPoint: # si drapeau point à False (not à True...)
                        self.lineEdit.setText(self.lineEdit.text()+".") # ajoute le caractère au champ
                        self.flagPoint=True # met le drapeau d'utilisation du point à True pour éviter réutilisation
                else:print("Point déjà utilisé") # affiche message

        def pushButton_ClearClicked(self):
                print("Bouton " + str(self.pushButton_Clear.text())+ " cliqué")
                self.lineEdit.setText("0") # défini le contenu du champ
                self.flagPoint=False # met le drapeau d'utilisation du point à False pour permettre réutilisation

        #-- fonctions de la classe
        #-- gestion du champ texte saisie valeur clavier
        def setLineEdit(self, charIn): # fonction reçoit le caractère (str)à ajouter au champ
                if self.lineEdit.text()=="0":self.lineEdit.setText(charIn) # efface contenu si vaut "0"
                else:self.lineEdit.setText(self.lineEdit.text()+charIn) # ajoute le caractère au champ

        #----- fonction de classe commune d'envoi d'une chaîne sur le port série ----
        def envoiChaineSerie(self, chaineIn): # la fonction reçoit un objet chaîne Str

                if self.serialPort: # seulement si le port série existe - n'existe pas (=None) tant que pas initialisé

                        self.timer.stop() # stoppe le timer le temps d'envoyer message sur le port série               

                        # combobox avec index 0 = rien, 1=saut de ligne (LF), 2=retour chariot (CR), 3= les 2 LF+CR
                        if self.comboBoxFinLigne.currentIndex()==0: # si rien sélectionné
                                # self.serialPort.write(str(self.lineEditChaineEnvoi.text())+'\n'  ) # envoie la chaine sur le port serie              
                                self.serialPort.write(chaineIn)  # envoie la chaine sur le port serie   - variante ascii       
                                print("Envoi Série : " + chaineIn )
                                self.textEditTraceEnvoiSerie.append(chaineIn) # ajoute texteEdit de visualisation

                        if self.comboBoxFinLigne.currentIndex()==1: # si saut de ligne sélectionné
                                self.serialPort.write(chaineIn +chr(10) ) # envoie la chaine sur le port serie  - variante ascii       
                                print("Envoi Série : " + chaineIn + '\n')
                                self.textEditTraceEnvoiSerie.append(chaineIn) # ajoute texteEdit de visualisation

                        if self.comboBoxFinLigne.currentIndex()==2: # si retour chariot sélectionné
                                self.serialPort.write(chaineIn+chr(13)  ) # envoie la chaine sur le port serie  - variante ascii       
                                print("Envoi Série : " + chaineIn + '\r')
                                self.textEditTraceEnvoiSerie.append(chaineIn) # ajoute texteEdit de visualisation

                        if self.comboBoxFinLigne.currentIndex()==3: # si saut de ligne + retour chariot sélectionné
                                self.serialPort.write(chaineIn+chr(10)+chr(13)  ) # envoie la chaine sur le port serie  - variante ascii
                                print("Envoi Série : " + chaineIn + '\n'+'\r')
                                self.textEditTraceEnvoiSerie.append(chaineIn) # ajoute texteEdit de visualisation

                        self.timer.start() # redémarre le timer - laisse délai pour réception en réinitialisation Timer à 0
                        # car sinon l'appui survient n'importe quand et si survient peu de temps avant fin délai
                        # la réception est hachée

        #--- fin envoiChaineSerie

        #----- fonction de gestion du signal timeout du QTimer
        def timerEvent(self): # fonction appelée lors de la survenue d'un évènement Timer - nom fonction indiférrent
                #-- variables de réception --
                self.chaineIn="";
                self.char="";

                # lecture des données reçues           
                if self.serialPort: # seulement si le port série existe
                        self.timer.stop() # stoppe le timer le temps de lire les caractères et éviter "réentrée"

                        while (self.serialPort.inWaiting()): # tant que au moins un caractère en réception
                                self.char=self.serialPort.read() # on lit le caractère
                                if self.char=='\n': # si saut de ligne, on sort du while
                                        print("saut ligne reçu") # debug
                                        break # sort du while
                                else: #tant que c'est pas le saut de ligne, on l'ajoute à la chaine
                                        self.chaineIn=self.chaineIn+self.char                                  

                        if len(self.chaineIn)>0: # ... pour ne pas avoir d'affichage si ""     
                                print(self.chaineIn) # affiche la chaîne
                                self.textEditReception.append(self.chaineIn[:-1]) # ajoute le texte au textEdit en enlevant le dernier caractère

                        self.timer.start() # redémarre le timer

        #---- fin timerEvent


def main(args):
        a=QApplication(args) # crée l'objet application
        f=QWidget() # crée le QWidget racine
        c=myApp(f) # appelle la classe contenant le code de l'application
        f.show() # affiche la fenêtre QWidget
        r=a.exec_() # lance l'exécution de l'application
        return r

if __name__=="__main__": # pour rendre le code exécutable
        main(sys.argv) # appelle la fonction main

 

Code Arduino d'exemple

// Miroir Série : renvoie la chaine recue sur le port série
// par X. HINAULT – www.mon-club-elec.fr

// --- Déclaration des variables globales ---

 int octetReception=0; // variable de stockage des valeurs reçues sur le port Série
 String chaineReception=""; // déclare un objet String vide pour reception chaine

// ////////////////////////// 2. FONCTION SETUP = Code d'initialisation //////////////////////////
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme

void setup()   { // debut de la fonction setup()


Serial.begin(115200); // initialise connexion série à 115200 bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission


} // fin de la fonction setup()
// ********************************************************************************

////////////////////////////////// 3. FONCTION LOOP = Boucle sans fin = coeur du programme //////////////////
// la fonction loop() s'exécute sans fin en boucle aussi longtemps que l'Arduino est sous tension

void loop(){ // debut de la fonction loop()


//---- code type réception chaine sur le port série ---
while (Serial.available()>0) { // tant qu'un octet en réception
        octetReception=Serial.read(); // Lit le 1er octet reçu et le met dans la variable

        if (octetReception==10) { // si Octet reçu est le saut de ligne
                Serial.println (chaineReception); // affiche la chaine recue
                chaineReception=""; //RAZ le String de réception
                break; // sort de la boucle while
        }
        else { // si le caractère reçu n'est pas un saut de ligne
                chaineReception=chaineReception+char(octetReception); // ajoute le caratère au String
                //Serial.print(char(octetReception)); // affiche la chaine recue
        }

} // fin tant que  octet réception


//----- une fois que le saut de ligne est reçu, on sort du While et on se positionne ici

} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
// ********************************************************************************

Utilisation

  • Les 2 fichiers suivants sont à enregistrer dans un même répertoire, l'un en nom.py et l'autre en nomMain.py.
  • Puis lancer l'application depuis Geany ou équivalent, en exécutant le fichier nomMain.py
  • Initialiser le port série
  • Saisir une valeur au clavier puis clic sur envoi de la chaine voulue.