2017-10-21 26 views
0

Je suis assez nouveau pour faire une interface graphique. J'ai conçu un pour un projet que je voudrais mettre à jour LCDs que les données viennent de l'Arduino. J'utilise pyqt5 pour convertir mon interface graphique Qtdesigner. Le problème est que je ne sais pas comment lier les données entrantes à l'interface graphique.Liaison de données en direct d'un Arduino à un LCDnumber de pyqt5 avec python3.5

Actuellement, j'ai un programme qui rassemble toutes les données que je voudrais et il ouvre l'affichage qui a été créé par Qtdesigner. Dans l'image ci-jointe, l'écran LCD sélectionné est appelé: lcdNumber_4 dans le nom de l'objet.

enter image description here

""" 
SCSU DYNO GUI PROGRAM 

created 10/20/2017 

""" 


import sys 
import time 
import serial 
import serial.tools.list_ports 
from PyQt5 import QtCore, QtGui, QtWidgets 
from PyQt5.QtCore import QThread,QTimer 
from PyQt5.QtWidgets import QMessageBox,QWidget 
from DynoTest1 import Ui_DynoTest1 
import csv 
import numpy as np 
import warnings 
import serial 
import serial.tools.list_ports 

__author__ = 'Matt Munn' 

class GetData(QThread): 
    def __init__(self):   

     QThread.__init__(self) 

     arduino_ports = [ # automatically searches for an Arduino and selects the port it's on 
      p.device 
      for p in serial.tools.list_ports.comports() 
      if 'Arduino' in p.description 
     ] 
     if not arduino_ports: 
      raise IOError("No Arduino found - is it plugged in? If so, restart computer.") 
     if len(arduino_ports) > 1: 
      warnings.warn('Multiple Arduinos found - using the first') 
     self.ArduinoData = serial.Serial(arduino_ports[0], 9600, timeout = 1) 
     self.ArduinoData.close() 
     self.ArduinoData.open() 


     self.Arduino.flush() 
     self.Arduino.reset_input_buffer() 

     start_time=time.time() 
     Distance = 0.5 # This is how long the lever arm is in feet 

    def __del__(self): # part of the standard format of a QThread 

     self.wait() 
    def run(self): # also a required QThread function, the working part  

     while True: 
      while (Arduino.inWaiting()==0): 
       pass 
      try: 
       data = Arduino.readline() 
       dataarray = data.decode().rstrip().split(',') 
       Arduino.reset_input_buffer() 
       Force = round(float(dataarray[0]),3) 
       RPM = round(float (dataarray[1]),3) 
       Torque = round(Force * Distance,3) 
       HorsePower = round(Torque * RPM/5252,3) 
       Run_Time = round(time.time()-start_time,3) 
       print (Force , 'Grams',"," , RPM ,'RPMs',"," ,Torque,"ft-lbs",",", HorsePower, "hp", Run_Time, "Time Elasped") 
      except (KeyboardInterrupt, SystemExit,IndexError,ValueError): 
       pass 


class GUI(Ui_DynoTest1): # create GUI and functionality 



    def __init__(self): 
     self.MainWindow = QtWidgets.QWidget() # pull code from DynoTest1.py and initialize 
     self.setupUi(self.MainWindow) 




def main(): # follow PYQT5 proper format for a GUI 

    app=QtWidgets.QApplication(sys.argv)  
    Dyno = GUI() 
    Dyno.MainWindow.show() 
    sys.exit(app.exec_()) 
# In[8]: 
if __name__ == '__main__': 

    main() 

# -*- coding: utf-8 -*- 

# Form implementation generated from reading ui file 'dynotest1.ui' 
# 
# Created by: PyQt5 UI code generator 5.9 
# 
# WARNING! All changes made in this file will be lost! 

from PyQt5 import QtCore, QtGui, QtWidgets 

class Ui_DynoTest1(object): 
    def setupUi(self, DynoTest1): 
     DynoTest1.setObjectName("DynoTest1") 
     DynoTest1.resize(1001, 695) 
     self.verticalLayout_4 = QtWidgets.QVBoxLayout(DynoTest1) 
     self.verticalLayout_4.setObjectName("verticalLayout_4") 
     self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 
     self.horizontalLayout_2.setObjectName("horizontalLayout_2") 
     self.horizontalLayout = QtWidgets.QHBoxLayout() 
     self.horizontalLayout.setObjectName("horizontalLayout") 
     self.verticalLayout_3 = QtWidgets.QVBoxLayout() 
     self.verticalLayout_3.setObjectName("verticalLayout_3") 
     self.gridLayout = QtWidgets.QGridLayout() 
     self.gridLayout.setObjectName("gridLayout") 
     self.pushButton_2 = QtWidgets.QPushButton(DynoTest1) 
     self.pushButton_2.setObjectName("pushButton_2") 
     self.gridLayout.addWidget(self.pushButton_2, 1, 0, 1, 1) 
     self.pushButton_4 = QtWidgets.QPushButton(DynoTest1) 
     self.pushButton_4.setObjectName("pushButton_4") 
     self.gridLayout.addWidget(self.pushButton_4, 1, 1, 1, 1) 
     self.pushButton_3 = QtWidgets.QPushButton(DynoTest1) 
     self.pushButton_3.setObjectName("pushButton_3") 
     self.gridLayout.addWidget(self.pushButton_3, 0, 1, 1, 1) 
     self.pushButton = QtWidgets.QPushButton(DynoTest1) 
     self.pushButton.setObjectName("pushButton") 
     self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1) 
     self.verticalLayout_3.addLayout(self.gridLayout) 
     self.label_3 = QtWidgets.QLabel(DynoTest1) 
     self.label_3.setObjectName("label_3") 
     self.verticalLayout_3.addWidget(self.label_3) 
     self.label_2 = QtWidgets.QLabel(DynoTest1) 
     self.label_2.setObjectName("label_2") 
     self.verticalLayout_3.addWidget(self.label_2) 
     self.label = QtWidgets.QLabel(DynoTest1) 
     self.label.setObjectName("label") 
     self.verticalLayout_3.addWidget(self.label) 
     self.horizontalLayout.addLayout(self.verticalLayout_3) 
     self.verticalLayout = QtWidgets.QVBoxLayout() 
     self.verticalLayout.setObjectName("verticalLayout") 
     self.label_5 = QtWidgets.QLabel(DynoTest1) 
     self.label_5.setObjectName("label_5") 
     self.verticalLayout.addWidget(self.label_5) 
     self.lcdNumber_4 = QtWidgets.QLCDNumber(DynoTest1) 
     self.lcdNumber_4.setObjectName("lcdNumber_4") 
     self.verticalLayout.addWidget(self.lcdNumber_4) 
     self.lcdNumber_5 = QtWidgets.QLCDNumber(DynoTest1) 
     self.lcdNumber_5.setObjectName("lcdNumber_5") 
     self.verticalLayout.addWidget(self.lcdNumber_5) 
     self.lcdNumber_6 = QtWidgets.QLCDNumber(DynoTest1) 
     self.lcdNumber_6.setObjectName("lcdNumber_6") 
     self.verticalLayout.addWidget(self.lcdNumber_6) 
     self.horizontalLayout.addLayout(self.verticalLayout) 
     self.verticalLayout_2 = QtWidgets.QVBoxLayout() 
     self.verticalLayout_2.setObjectName("verticalLayout_2") 
     self.label_6 = QtWidgets.QLabel(DynoTest1) 
     self.label_6.setObjectName("label_6") 
     self.verticalLayout_2.addWidget(self.label_6) 
     self.lcdNumber = QtWidgets.QLCDNumber(DynoTest1) 
     self.lcdNumber.setObjectName("lcdNumber") 
     self.verticalLayout_2.addWidget(self.lcdNumber) 
     self.lcdNumber_2 = QtWidgets.QLCDNumber(DynoTest1) 
     self.lcdNumber_2.setObjectName("lcdNumber_2") 
     self.verticalLayout_2.addWidget(self.lcdNumber_2) 
     self.lcdNumber_3 = QtWidgets.QLCDNumber(DynoTest1) 
     self.lcdNumber_3.setObjectName("lcdNumber_3") 
     self.verticalLayout_2.addWidget(self.lcdNumber_3) 
     self.horizontalLayout.addLayout(self.verticalLayout_2) 
     self.horizontalLayout_2.addLayout(self.horizontalLayout) 
     self.verticalLayout_5 = QtWidgets.QVBoxLayout() 
     self.verticalLayout_5.setObjectName("verticalLayout_5") 
     self.label_7 = QtWidgets.QLabel(DynoTest1) 
     self.label_7.setObjectName("label_7") 
     self.verticalLayout_5.addWidget(self.label_7) 
     self.lcdNumber_7 = QtWidgets.QLCDNumber(DynoTest1) 
     self.lcdNumber_7.setObjectName("lcdNumber_7") 
     self.verticalLayout_5.addWidget(self.lcdNumber_7) 
     self.horizontalLayout_2.addLayout(self.verticalLayout_5) 
     self.verticalLayout_4.addLayout(self.horizontalLayout_2) 
     self.graphicsView = QtWidgets.QGraphicsView(DynoTest1) 
     self.graphicsView.setStyleSheet("border-image: url(:/newPrefix/husky_head5.png);") 
     self.graphicsView.setObjectName("graphicsView") 
     self.verticalLayout_4.addWidget(self.graphicsView) 

     self.retranslateUi(DynoTest1) 
     QtCore.QMetaObject.connectSlotsByName(DynoTest1) 

    def retranslateUi(self, DynoTest1): 
     _translate = QtCore.QCoreApplication.translate 
     DynoTest1.setWindowTitle(_translate("DynoTest1", "DynoTest1")) 
     self.pushButton_2.setText(_translate("DynoTest1", "Pause")) 
     self.pushButton_4.setText(_translate("DynoTest1", "Print")) 
     self.pushButton_3.setText(_translate("DynoTest1", "Stop")) 
     self.pushButton.setText(_translate("DynoTest1", "Start")) 
     self.label_3.setText(_translate("DynoTest1", "<html><head/><body><p align=\"center\"><span style=\" font-size:18pt; font-weight:600;\">RPMs</span></p></body></html>")) 
     self.label_2.setText(_translate("DynoTest1", "<html><head/><body><p align=\"center\"><span style=\" font-size:18pt; font-weight:600;\">Torque (ft-lbs)</span></p></body></html>")) 
     self.label.setText(_translate("DynoTest1", "<html><head/><body><p align=\"center\"><span style=\" font-size:18pt; font-weight:600;\">Horse Power</span></p></body></html>")) 
     self.label_5.setText(_translate("DynoTest1", "<html><head/><body><p align=\"center\"><span style=\" font-size:18pt; font-weight:600;\">Now</span></p></body></html>")) 
     self.label_6.setText(_translate("DynoTest1", "<html><head/><body><p align=\"center\"><span style=\" font-size:18pt; font-weight:600;\">Max</span></p></body></html>")) 
     self.label_7.setText(_translate("DynoTest1", "<html><head/><body><p align=\"center\"><span style=\" font-size:18pt; font-weight:600;\">Run Time</span></p></body></html>")) 

import Resource_rc 
+0

Qu'est-ce que 'self.Arduino'? – eyllanesc

+0

Si je me souviens bien, cela aide à configurer l'utilisation de l'arduino. Je ne suis en aucun cas un expert en codage, donc s'il y a d'autres améliorations à apporter, n'hésitez pas à me le faire savoir. Je vous remercie. –

+0

Avez-vous écrit ce code? – eyllanesc

Répondre

0

Pour le bon fonctionnement, je l'ai modifié le nom de certaines variables, car ils ne correspondent pas à leur utilisation. Afin d'envoyer des informations entre les éléments de PyQt, il est conseillé d'utiliser des signaux et des slots, pour cela, vous devez créer un signal en QThread qui envoie les informations qui doivent être affichées dans l'interface graphique pour cela, nous utilisons pyqtSignal() où nous indiquons les types des paramètres qui vont envoyer.

class GetData(QThread): 
    dataChanged = pyqtSignal(float, float, float, float) 
    Distance = 0.5 

    def __init__(self, parent=None): 
     QThread.__init__(self, parent) 

     arduino_ports = [ # automatically searches for an Arduino and selects the port it's on 
      p.device 
      for p in serial.tools.list_ports.comports() 
      if 'Arduino' in p.description 
     ] 

     if not arduino_ports: 
      raise IOError("No Arduino found - is it plugged in? If so, restart computer.") 
     if len(arduino_ports) > 1: 
      warnings.warn('Multiple Arduinos found - using the first') 
     self.Arduino = serial.Serial(arduino_ports[0], 9600, timeout=1) 

    def __del__(self): # part of the standard format of a QThread 
     self.wait() 

    def run(self): # also a required QThread function, the working part 
     self.Arduino.close() 
     self.Arduino.open() 

     self.Arduino.flush() 
     self.Arduino.reset_input_buffer() 
     start_time = time.time() 

     while True: 
      while self.Arduino.inWaiting() == 0: 
       pass 
      try: 
       data = self.Arduino.readline() 
       dataarray = data.decode().rstrip().split(',') 
       self.Arduino.reset_input_buffer() 
       Force = round(float(dataarray[0]), 3) 
       RPM = round(float(dataarray[1]), 3) 
       Torque = round(Force * GetData.Distance, 3) 
       HorsePower = round(Torque * RPM/5252, 3) 
       Run_Time = round(time.time() - start_time, 3) 
       print(Force, 'Grams', ",", RPM, 'RPMs', ",", Torque, "ft-lbs", ",", HorsePower, "hp", Run_Time, 
         "Time Elasped") 
       self.dataChanged.emit(RPM, Torque, HorsePower, Run_Time) 
      except (KeyboardInterrupt, SystemExit, IndexError, ValueError): 
       pass 

Qt Designer offre une conception, ne fournit pas un widget, pour qu'il est préférable de créer un Hériter de classe à partir d'un widget et utiliser la conception, créer une instance de QThread et connecter le signal dataChanged à une fente , et dans cet emplacement est où nous plaçons les valeurs dans le QLCDNumber.

class GUI(QWidget, Ui_DynoTest1): 
    def __init__(self, parent=None): 
     QWidget.__init__(self, parent) 
     self.setupUi(self) 
     self.thread = GetData(self) 
     self.thread.dataChanged.connect(self.onDataChanged) 
     self.thread.start() 

    def onDataChanged(self, RPM, Torque, HorsePower, Run_Time): 
     self.lcdNumber_4.display(RPM) 
     self.lcdNumber_5.display(Torque) 
     self.lcdNumber_6.display(HorsePower) 
     self.lcdNumber_7.display(Run_Time) 


if __name__ == '__main__': 
    import sys 
    app = QApplication(sys.argv) 
    Dyno = GUI() 
    Dyno.show() 
    sys.exit(app.exec_()) 
+0

Bonjour encore, je me demandais si vous aviez une idée sur la façon d'obtenir les LCD pour afficher les décimales et pas seulement les entiers? Fait-il partie du code, ou fait-il partie du QTDesigner?Ce que j'ai vu jusqu'ici, c'est que par défaut, il ne fait que des entiers, et je suis sûr que ce que vous avez vu dans mon code est que j'essaie d'arrondir mes valeurs à une certaine décimale. Je vous remercie! –

+0

J'ai changé la ligne suivante 'dataChanged = pyqtSignal (float, float, float, float)', essayez avec cette modification – eyllanesc

+0

Yup, qui a fait l'affaire, Donc, c'est un truc de code où vous définissez les lcd aux entiers. Je vous remercie. –