codeCleaning
This commit is contained in:
parent
428d869382
commit
8e38486872
849
GUI_22_10_staticWorkflow_Multithreading.py
Normal file
849
GUI_22_10_staticWorkflow_Multithreading.py
Normal file
@ -0,0 +1,849 @@
|
|||||||
|
|
||||||
|
#from PyQt5 import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QProgressBar
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
from PyQt5.QtWidgets import QApplication, QComboBox
|
||||||
|
from PyQt5.QtCore import QTimer, QThread, pyqtSignal, QObject, Qt
|
||||||
|
from PyQt5.QtGui import QColor
|
||||||
|
|
||||||
|
import serial
|
||||||
|
import binascii
|
||||||
|
import math
|
||||||
|
import mariadb
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
|
||||||
|
|
||||||
|
db_config = {
|
||||||
|
'user': 'dbUser',
|
||||||
|
'password': 'dbPassword',
|
||||||
|
'host': 'localhost',
|
||||||
|
'database': 'projectGeislinger',
|
||||||
|
'port': 3306 # Standard port for MariaDB
|
||||||
|
}
|
||||||
|
|
||||||
|
# Establishing the connection
|
||||||
|
conn = mariadb.connect(**db_config)
|
||||||
|
# Create a cursor to execute queries
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Konfiguration der seriellen Schnittstelle
|
||||||
|
ser = serial.Serial('/dev/ttyUSB0', 9600)
|
||||||
|
#ser = serial.Serial('/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0', 9600) #dadurch garantiert immer die gleiche Schnittstelle verwendet
|
||||||
|
# und nicht die Schnittstelle, welche die Bezeichnung ttyUSB0 verwendet (welche sich ändern könnte)
|
||||||
|
# um die ID der USB-Schnittstelle heraus zu finden im Terminal folgendes eingeben: ls -l /dev/serial/by-id/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#class Worker(QThread):
|
||||||
|
class Worker(QObject):
|
||||||
|
#progress = pyqtSignal(int)
|
||||||
|
objectDetectionStartSignal = pyqtSignal(str)
|
||||||
|
objectDetectionFinishedSignal = pyqtSignal(int, object)
|
||||||
|
|
||||||
|
checkWaageStartSignal = pyqtSignal(int, int, str)
|
||||||
|
checkWaageUpdateSignal = pyqtSignal(int, int)
|
||||||
|
checkWaageFinishedSignal = pyqtSignal(int)
|
||||||
|
|
||||||
|
waageStoppedSignal = pyqtSignal(int)
|
||||||
|
stopLoopSignal = pyqtSignal(bool) #das Signal wird verwendet um direkt den stopLoop-Wert zu ändern (also kein Funktionsaufruf)
|
||||||
|
|
||||||
|
stopLoop = False
|
||||||
|
btTypeIsSet = False
|
||||||
|
correctBtNr = False
|
||||||
|
waageEingeschwungen = False
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(Worker, self).__init__()
|
||||||
|
stopLoop = False
|
||||||
|
|
||||||
|
def wahrscheinlichkeitsDichte(self, x, mue, var):
|
||||||
|
# in der Funktion wird der Wahrscheinlichkeitsdichtenwert der Variable x für eine bestimmte Normalverteilung berechnet
|
||||||
|
standardabweichung = var**0.5
|
||||||
|
|
||||||
|
result = 1/(standardabweichung * (2*math.pi)**0.5 ) * math.exp(-0.5 * ((x-mue)/standardabweichung)**2)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def getDataOfArticleType(self, allArticles, articleType):
|
||||||
|
# die Funktion geht die Liste mit allen Artikeln durch und gibt jenen Eintrag, welcher mit dem "articleType" übereinstimmt zurück
|
||||||
|
for i in allArticles:
|
||||||
|
if i[1] == articleType:
|
||||||
|
return i
|
||||||
|
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def waageNichtEingeschwungenOutput(self):
|
||||||
|
print("Die Waage ist noch nicht eingeschwungen - Ergebnisse sind dadurch noch fehlerhaft.")
|
||||||
|
|
||||||
|
def readWaage(self):
|
||||||
|
# in folgender Funktion wird die Waage ausgelesen
|
||||||
|
|
||||||
|
#print("connection is open: ", ser.is_open) #Debuggingausgabe
|
||||||
|
#print("port to which it is connected: ", ser.portstr) #Debuggingausgabe
|
||||||
|
|
||||||
|
|
||||||
|
if ser.is_open == False:
|
||||||
|
ser.open()
|
||||||
|
|
||||||
|
|
||||||
|
#an die Waage den Befehl senden, dass sie ausgelesen werden soll
|
||||||
|
ser.write(b'getWeight\n')
|
||||||
|
#ser.write(b'tare\n')
|
||||||
|
serialString = ser.readline().decode('utf-8').rstrip() #Auslesen des Serial-Strings/der Messung der Waage
|
||||||
|
|
||||||
|
# wenn am Ende des Strings kg steht, dann ist die Waage eingeschwungen - das wird hiermit überprüft
|
||||||
|
lenString = len(serialString)-1
|
||||||
|
if serialString[lenString] == "g" and serialString[lenString-1] == "k":
|
||||||
|
#print("ist eingeschwungen") #Debuggingausgabe
|
||||||
|
self.waageEingeschwungen = True
|
||||||
|
else:
|
||||||
|
print("die Waage ist noch nicht eingeschwungen")
|
||||||
|
self.waageEingeschwungen = False
|
||||||
|
|
||||||
|
#aus dem String werden alle Zeichen, welche nicht zur Darstellung der Zahl benötigt werden entfernt
|
||||||
|
intString = ""
|
||||||
|
for i in serialString:
|
||||||
|
if i=="-" or i=="0" or i=="." or i=="1" or i=="2" or i=="3" or i=="4" or i=="5" or i=="6" or i=="7" or i=="8" or i=="9":
|
||||||
|
intString = intString + i
|
||||||
|
print("Wert, welcher von der Waage ausgelesen wurde: " + intString + "kg")
|
||||||
|
## Waage auslesen - ENDE
|
||||||
|
|
||||||
|
ser.close()
|
||||||
|
#print("connection is open: ", ser.is_open) #Debuggingausgabe
|
||||||
|
|
||||||
|
return self.waageEingeschwungen, intString
|
||||||
|
|
||||||
|
def objectTypeDetectionThread(self, auftragsnummer):
|
||||||
|
# in dieser Funktion wird der Typ des Bauteils automatisch erkannt
|
||||||
|
|
||||||
|
#print("objectTypeDetectionThread - Running in thread:", threading.current_thread().name) #Debuggausgabe
|
||||||
|
|
||||||
|
# Parameterdefinition
|
||||||
|
propDensVect = []
|
||||||
|
|
||||||
|
self.btTypeIsSet = False
|
||||||
|
|
||||||
|
while(self.btTypeIsSet == False and self.stopLoop == False):
|
||||||
|
|
||||||
|
# Auslesen der Waage
|
||||||
|
self.waageEingeschwungen, intString = self.readWaage()
|
||||||
|
if self.waageEingeschwungen == False:
|
||||||
|
self.waageNichtEingeschwungenOutput()
|
||||||
|
else:
|
||||||
|
|
||||||
|
# Datenbankabfrage
|
||||||
|
sql_query = "SELECT Auftraege.id, EinzelteilID, Auftragsnummer, Anzahl, Einzelteile.id, Bezeichnung, CAST(projectGeislinger.Einzelteile.GewichtMittelwert AS CHAR), CAST(projectGeislinger.Einzelteile.GewichtVarianz AS CHAR) FROM projectGeislinger.Auftraege, projectGeislinger.Einzelteile where projectGeislinger.Auftraege.EinzelteilID = projectGeislinger.Einzelteile.id AND projectGeislinger.Auftraege.Auftragsnummer = " + auftragsnummer
|
||||||
|
cursor.execute(sql_query)
|
||||||
|
auftragEinzelteilDaten = cursor.fetchall()
|
||||||
|
|
||||||
|
'''
|
||||||
|
# Display data #Debugausgabe
|
||||||
|
print("Ausgabe der Auftragsdetails des obigen Auftrags, inklusive Einzelteildetails:")
|
||||||
|
for row in auftragEinzelteilDaten:
|
||||||
|
print(row)
|
||||||
|
'''
|
||||||
|
|
||||||
|
# in der Folge werden alle Wahrscheinlichkeitsdichten der Auftragsbauteile berechnet und in dem Vektor gesammelt
|
||||||
|
for row in auftragEinzelteilDaten:
|
||||||
|
propDensVect.append([self.wahrscheinlichkeitsDichte(float(intString),float(row[6]), float(row[7])), row[1], row[5]])
|
||||||
|
|
||||||
|
# Jenen Eintrag des propDensVect raussuchen, welcher die größte Wahrscheinlichkeitsdichte beinhaltet
|
||||||
|
maxpropDens = 0
|
||||||
|
einzelteilID = 0
|
||||||
|
rowData = None
|
||||||
|
for row in propDensVect:
|
||||||
|
if row[0] > maxpropDens:
|
||||||
|
maxpropDens = row[0]
|
||||||
|
einzelteilID = row[1]
|
||||||
|
rowData = row
|
||||||
|
|
||||||
|
# überprüfen, ob das aufliegende Bauteil in der Auftragstabelle vorhanden ist
|
||||||
|
if(einzelteilID == 0):
|
||||||
|
print("Es wurde kein Bauteil aus der Auftragsliste (Tabelle) erkannt.")
|
||||||
|
else:
|
||||||
|
print("Bei dem Bauteil" , einzelteilID , "wurde die höchste Wahrscheinlichkeitsdichte berechnet.")
|
||||||
|
|
||||||
|
'''
|
||||||
|
# Wahrscheinlichkeit berechnen, dass das angegebene Bauteil auch wirklich diesem entspricht
|
||||||
|
prop = 0
|
||||||
|
for row in auftragEinzelteilDaten:
|
||||||
|
if row[1] == einzelteilID:
|
||||||
|
prop = calcWahrscheinlichkeitFromDichte(float(intString),float(row[6]), float(row[7]))
|
||||||
|
break
|
||||||
|
print("Die Wahrscheinlichkeit, dass es das Bauteil ist, beträgt: ", prop)
|
||||||
|
'''
|
||||||
|
|
||||||
|
# den Bool auf true setzen, damit die Schleife beendet wird - dieser wird auf True gesetzt, wenn ein Bauteiltyp erkannt wird
|
||||||
|
self.btTypeIsSet = True
|
||||||
|
|
||||||
|
if(self.stopLoop == False):
|
||||||
|
# ein Signal zurück an den MainThreat senden, mit den Infos/Ergebnissen, der Typenbestimmung
|
||||||
|
self.objectDetectionFinishedSignal.emit(einzelteilID, rowData)
|
||||||
|
else:
|
||||||
|
self.waageStoppedSignal.emit(einzelteilID)
|
||||||
|
|
||||||
|
def checkWaageThread(self, einzelteilID, teileZuViel, auftragsnummer):
|
||||||
|
|
||||||
|
self.correctBtNr = False
|
||||||
|
prevAnzahl = -1
|
||||||
|
anzahl = 0
|
||||||
|
einzelteilID = einzelteilID
|
||||||
|
|
||||||
|
while (self.correctBtNr == False and self.stopLoop == False):
|
||||||
|
|
||||||
|
#überprüfen, ob die Waage eingeschwungen ist (und damit korrekte Ergebnisse liefert)
|
||||||
|
self.waageEingeschwungen, intString = self.readWaage()
|
||||||
|
if self.waageEingeschwungen == False:
|
||||||
|
self.waageNichtEingeschwungenOutput()
|
||||||
|
else:
|
||||||
|
|
||||||
|
# Datenbankabfrage - holen der Auftrags- und Bauteilinfos
|
||||||
|
sql_query = "SELECT Auftraege.id, EinzelteilID, Auftragsnummer, Anzahl, Einzelteile.id, Bezeichnung, CAST(projectGeislinger.Einzelteile.GewichtMittelwert AS CHAR), CAST(projectGeislinger.Einzelteile.GewichtVarianz AS CHAR) FROM projectGeislinger.Auftraege, projectGeislinger.Einzelteile where projectGeislinger.Auftraege.EinzelteilID = projectGeislinger.Einzelteile.id AND projectGeislinger.Auftraege.Auftragsnummer = " + auftragsnummer
|
||||||
|
cursor.execute(sql_query)
|
||||||
|
auftragDaten = cursor.fetchall()
|
||||||
|
|
||||||
|
'''
|
||||||
|
# Display data - zum Debuggen
|
||||||
|
print("Ausgabe der Auftragsdetails:")
|
||||||
|
print("id|EinzelteilID|Auftragsnummer|Anzahl")
|
||||||
|
for row in auftragDaten:
|
||||||
|
print(row)
|
||||||
|
'''
|
||||||
|
|
||||||
|
#auslesen, wie viele Bauteile des Types laut Auftrag vorhanden sein sollen
|
||||||
|
anzBauteile_soll = 0
|
||||||
|
idVorhanden = False
|
||||||
|
|
||||||
|
for row in auftragDaten:
|
||||||
|
if row[1] == einzelteilID:
|
||||||
|
anzBauteile_soll = row[3]
|
||||||
|
idVorhanden = True
|
||||||
|
|
||||||
|
if(idVorhanden == False):
|
||||||
|
print("Die gewählte Pos.Nr ist nicht in der Auftragsliste (Tabelle) vorhanden.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Berechnen der Wahrscheinlichkeitsdichten - der Betrag aller Wahrscheinlichkeitsdichten werden im propDensVect gespeichert
|
||||||
|
propDensVect = []
|
||||||
|
articleData = self.getDataOfArticleType(auftragDaten, einzelteilID)
|
||||||
|
#for i in range(1,anzBauteile_soll+teileZuViel+1):
|
||||||
|
for i in range(0,anzBauteile_soll+teileZuViel+1):
|
||||||
|
# Mathematische Sätze, auf welchen die Berechnung basiert:
|
||||||
|
# seien X1,..., Xn unabhängige Zufallsvariablen die N(mue_i, sigma_i^2) verteilt sind, dann ist X = X1+...+Xn - N(mue, sigma^2) verteilt mit mue=mue1+...+mue_n, sigma^2 = sigma_1^2+...+sigma_n^2
|
||||||
|
mueGes = float(articleData[6])*i # Berechnen des äquivalenten Mittelwert
|
||||||
|
# das if wird eingeführt, um auch die Bauteilanzahl 0 korrekt berücksichtigen zu können
|
||||||
|
if i == 0:
|
||||||
|
varGes = float(articleData[7])
|
||||||
|
else:
|
||||||
|
varGes = float(articleData[7])*i # Berechnen der äquivalenten Varianz
|
||||||
|
propDensVect.append([self.wahrscheinlichkeitsDichte(float(intString),mueGes, varGes), i])
|
||||||
|
|
||||||
|
# durch den propDensVect iterieren und jenen Eintrag mit der höchsten Wahrscheinlichkeitsdichte raussuchen
|
||||||
|
maxpropDens = 0
|
||||||
|
for row in propDensVect:
|
||||||
|
if row[0] > maxpropDens:
|
||||||
|
maxpropDens = row[0]
|
||||||
|
anzahl = row[1]
|
||||||
|
|
||||||
|
# damit nur etwas gemacht wird (zb ein Updatesignal an den Hauptthread zurücksenden), wenn sich die berechnete Anzahl ändert
|
||||||
|
if prevAnzahl != anzahl:
|
||||||
|
prevAnzahl = anzahl
|
||||||
|
|
||||||
|
'''
|
||||||
|
# Die Wahrscheinlichkeit berechnen, dass das obige Ergebnis auch dem Bauteil entspricht
|
||||||
|
if anzahl > 0:
|
||||||
|
for row in auftragDaten:
|
||||||
|
if row[1] == einzelteilID:
|
||||||
|
prop = calcWahrscheinlichkeitFromDichte(float(intString),float(row[6])*anzahl, float(row[7])*anzahl)
|
||||||
|
break
|
||||||
|
print("Die Wahrscheinlichkeit, dass es das Bauteil ist, beträgt: ", prop)
|
||||||
|
'''
|
||||||
|
|
||||||
|
# wenn genug Bauteile vorhanden sind, dann soll die Schleife beendet werden
|
||||||
|
if (anzahl == anzBauteile_soll):
|
||||||
|
self.correctBtNr = True
|
||||||
|
|
||||||
|
# Konsolenausgabe
|
||||||
|
if maxpropDens > 0:
|
||||||
|
print("Bei der Anzahl" , anzahl , "des Bauteiltypes", einzelteilID, ",wurde die höchste Wahrscheinlichkeitsdichte berechnet.")
|
||||||
|
self.checkWaageUpdateSignal.emit(einzelteilID, anzahl)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("Von der ausgewählten Bauteiltype liegt die berechnete Wahrscheinlichkeit bei 0, dass zwischen 0 und", anzBauteile_soll+teileZuViel, "Bauteilen auf der Waage liegen.")
|
||||||
|
print("Falls die korrekte Anzhl an Bauteilen auf der Waage liegt, könnte der Fehler in einer falschen Kalibrierung der Waage liegen (TARE).")
|
||||||
|
|
||||||
|
if(self.stopLoop == False):
|
||||||
|
self.checkWaageFinishedSignal.emit(einzelteilID)
|
||||||
|
else:
|
||||||
|
self.waageStoppedSignal.emit(einzelteilID)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Ui_MainWindow(object):
|
||||||
|
def setupUi(self, MainWindow):
|
||||||
|
self.auftragsnummer = ""
|
||||||
|
self.teileZuViel = 100 # Anzahl an Bauteilen, welche zu viel drinnen sein können - der Parameter kann selbst gesetzt werden #####
|
||||||
|
self.correctBtNr = False
|
||||||
|
self.btTypeIsSet = False
|
||||||
|
|
||||||
|
|
||||||
|
MainWindow.setObjectName("MainWindow")
|
||||||
|
MainWindow.resize(1400, 675)
|
||||||
|
self.centralwidget = QtWidgets.QWidget(MainWindow)
|
||||||
|
self.centralwidget.setObjectName("centralwidget")
|
||||||
|
self.btn1 = QtWidgets.QPushButton(self.centralwidget)
|
||||||
|
self.btn1.setGeometry(QtCore.QRect(700, 45, 111, 25))
|
||||||
|
self.btn1.setObjectName("btn1")
|
||||||
|
# Tabelle zur Darstellung der Auftragsdetails
|
||||||
|
self.AuftragsdetailsTable = QtWidgets.QTableWidget(self.centralwidget)
|
||||||
|
self.AuftragsdetailsTable.setGeometry(QtCore.QRect(10, 100, 661, 400))
|
||||||
|
self.AuftragsdetailsTable.setObjectName("AuftragsdetailsTable")
|
||||||
|
self.AuftragsdetailsTable.setColumnCount(6)
|
||||||
|
self.AuftragsdetailsTable.setRowCount(0)
|
||||||
|
item = QtWidgets.QTableWidgetItem()
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setPointSize(8)
|
||||||
|
item.setFont(font)
|
||||||
|
self.AuftragsdetailsTable.setHorizontalHeaderItem(0, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem()
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setPointSize(8)
|
||||||
|
item.setFont(font)
|
||||||
|
self.AuftragsdetailsTable.setHorizontalHeaderItem(1, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem()
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setPointSize(8)
|
||||||
|
item.setFont(font)
|
||||||
|
self.AuftragsdetailsTable.setHorizontalHeaderItem(2, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem()
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setPointSize(8)
|
||||||
|
item.setFont(font)
|
||||||
|
self.AuftragsdetailsTable.setHorizontalHeaderItem(3, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem()
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setPointSize(8)
|
||||||
|
item.setFont(font)
|
||||||
|
self.AuftragsdetailsTable.setHorizontalHeaderItem(5, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem()
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setPointSize(8)
|
||||||
|
item.setFont(font)
|
||||||
|
self.AuftragsdetailsTable.setHorizontalHeaderItem(4, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem()
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setPointSize(8)
|
||||||
|
item.setFont(font)
|
||||||
|
self.AuftragsdetailsTable.setHorizontalHeaderItem(6, item)
|
||||||
|
|
||||||
|
# Tabelle zur Darstellung der Arbeitsschritte
|
||||||
|
self.ArbeitsschrittTable = QtWidgets.QTableWidget(self.centralwidget)
|
||||||
|
self.ArbeitsschrittTable.setGeometry(QtCore.QRect(1000, 50, 395, 400))
|
||||||
|
self.ArbeitsschrittTable.setObjectName("AuftragsdetailsTable")
|
||||||
|
self.ArbeitsschrittTable.setColumnCount(2)
|
||||||
|
self.ArbeitsschrittTable.setRowCount(4)
|
||||||
|
self.ArbeitsschrittTable.setColumnWidth(0, 100)
|
||||||
|
self.ArbeitsschrittTable.setColumnWidth(1, 280)
|
||||||
|
self.ArbeitsschrittTable.setRowHeight(0, 80)
|
||||||
|
self.ArbeitsschrittTable.setRowHeight(1, 180)
|
||||||
|
self.ArbeitsschrittTable.setRowHeight(2, 50)
|
||||||
|
self.ArbeitsschrittTable.setRowHeight(3, 50)
|
||||||
|
item = QtWidgets.QTableWidgetItem()
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setPointSize(8)
|
||||||
|
item.setFont(font)
|
||||||
|
self.ArbeitsschrittTable.setHorizontalHeaderItem(0, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem()
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setPointSize(8)
|
||||||
|
item.setFont(font)
|
||||||
|
self.ArbeitsschrittTable.setHorizontalHeaderItem(1, item)
|
||||||
|
|
||||||
|
self.label = QtWidgets.QLabel(self.centralwidget)
|
||||||
|
self.label.setGeometry(QtCore.QRect(500, 20, 121, 17))
|
||||||
|
self.label.setObjectName("label")
|
||||||
|
self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
|
||||||
|
self.textEdit.setGeometry(QtCore.QRect(450, 40, 221, 31))
|
||||||
|
self.textEdit.setObjectName("textEdit")
|
||||||
|
self.bauteilTypBtn = QtWidgets.QPushButton(self.centralwidget)
|
||||||
|
self.bauteilTypBtn.setGeometry(QtCore.QRect(700, 100, 161, 25))
|
||||||
|
self.bauteilTypBtn.setObjectName("bauteilTypBtn")
|
||||||
|
self.checkWaageBtn = QtWidgets.QPushButton(self.centralwidget)
|
||||||
|
self.checkWaageBtn.setGeometry(QtCore.QRect(700, 150, 161, 25))
|
||||||
|
self.checkWaageBtn.setObjectName("checkWaageBtn")
|
||||||
|
self.stopLoopBtn = QtWidgets.QPushButton(self.centralwidget)
|
||||||
|
self.stopLoopBtn.setGeometry(QtCore.QRect(700, 350, 161, 25))
|
||||||
|
self.stopLoopBtn.setObjectName("stopLoopBtn")
|
||||||
|
self.waageTareBtn = QtWidgets.QPushButton(self.centralwidget)
|
||||||
|
self.waageTareBtn.setGeometry(QtCore.QRect(700, 400, 161, 25))
|
||||||
|
self.waageTareBtn.setObjectName("waageTareBtn")
|
||||||
|
self.bauteiltypTextbox = QtWidgets.QTextEdit(self.centralwidget)
|
||||||
|
self.bauteiltypTextbox.setGeometry(QtCore.QRect(700, 290, 221, 31))
|
||||||
|
self.bauteiltypTextbox.setObjectName("bauteiltypTextbox")
|
||||||
|
self.BezeichnungLabel = QtWidgets.QLabel(self.centralwidget)
|
||||||
|
self.BezeichnungLabel.setGeometry(QtCore.QRect(700, 270, 181, 20))
|
||||||
|
self.BezeichnungLabel.setObjectName("BezeichnungLabel")
|
||||||
|
self.PosNrLabel = QtWidgets.QLabel(self.centralwidget)
|
||||||
|
self.PosNrLabel.setGeometry(QtCore.QRect(700, 200, 67, 17))
|
||||||
|
self.PosNrLabel.setObjectName("PosNrLabel")
|
||||||
|
self.PosNrTxtFeld = QtWidgets.QTextEdit(self.centralwidget)
|
||||||
|
self.PosNrTxtFeld.setGeometry(QtCore.QRect(700, 220, 191, 31))
|
||||||
|
self.PosNrTxtFeld.setObjectName("PosNrTxtFeld")
|
||||||
|
self.teileZuVielLabel = QtWidgets.QLabel(self.centralwidget)
|
||||||
|
self.teileZuVielLabel.setGeometry(QtCore.QRect(1000, 560, 350, 17))
|
||||||
|
self.teileZuVielLabel.setObjectName("teileZuVielLabel")
|
||||||
|
self.teileZuVielTxtFeld = QtWidgets.QTextEdit(self.centralwidget)
|
||||||
|
self.teileZuVielTxtFeld.setGeometry(QtCore.QRect(1000, 580, 191, 31))
|
||||||
|
MainWindow.setCentralWidget(self.centralwidget)
|
||||||
|
self.menubar = QtWidgets.QMenuBar(MainWindow)
|
||||||
|
self.menubar.setGeometry(QtCore.QRect(0, 0, 1090, 22))
|
||||||
|
self.menubar.setObjectName("menubar")
|
||||||
|
MainWindow.setMenuBar(self.menubar)
|
||||||
|
self.statusbar = QtWidgets.QStatusBar(MainWindow)
|
||||||
|
self.statusbar.setObjectName("statusbar")
|
||||||
|
MainWindow.setStatusBar(self.statusbar)
|
||||||
|
self.checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||||
|
self.checkBox.setGeometry(QtCore.QRect(1000, 480, 151, 23))
|
||||||
|
self.checkBox.setObjectName("checkBox")
|
||||||
|
self.checkBoxAutoTare = QtWidgets.QCheckBox(self.centralwidget)
|
||||||
|
self.checkBoxAutoTare.setGeometry(QtCore.QRect(1000, 520, 180, 23))
|
||||||
|
self.checkBoxAutoTare.setObjectName("checkBoxAutoTare")
|
||||||
|
|
||||||
|
self.retranslateUi(MainWindow)
|
||||||
|
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
||||||
|
|
||||||
|
def retranslateUi(self, MainWindow):
|
||||||
|
_translate = QtCore.QCoreApplication.translate
|
||||||
|
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
|
||||||
|
self.btn1.setText(_translate("MainWindow", "load Auftrag"))
|
||||||
|
self.btn1.clicked.connect(self.auftragsBtnClicked)
|
||||||
|
|
||||||
|
# Tabelle zur Darstellung der Auftragsdetails
|
||||||
|
item = self.AuftragsdetailsTable.horizontalHeaderItem(0)
|
||||||
|
item.setText(_translate("MainWindow", "Pos.-Nr"))
|
||||||
|
item = self.AuftragsdetailsTable.horizontalHeaderItem(1)
|
||||||
|
item.setText(_translate("MainWindow", "Matnr mit hoechster Version"))
|
||||||
|
item = self.AuftragsdetailsTable.horizontalHeaderItem(2)
|
||||||
|
item.setText(_translate("MainWindow", "Bezeichnung + Werkstoff"))
|
||||||
|
item = self.AuftragsdetailsTable.horizontalHeaderItem(3)
|
||||||
|
item.setText(_translate("MainWindow", "Soll-Menge"))
|
||||||
|
item = self.AuftragsdetailsTable.horizontalHeaderItem(4)
|
||||||
|
item.setText(_translate("MainWindow", "Ist-Menge"))
|
||||||
|
item = self.AuftragsdetailsTable.horizontalHeaderItem(5)
|
||||||
|
item.setText(_translate("MainWindow", "Lgort"))
|
||||||
|
|
||||||
|
# Tabelle zur Darstellung der Arbeitsschritte
|
||||||
|
item = self.ArbeitsschrittTable.horizontalHeaderItem(0)
|
||||||
|
item.setText(_translate("MainWindow", "Arbeitsschritt"))
|
||||||
|
item = self.ArbeitsschrittTable.horizontalHeaderItem(1)
|
||||||
|
item.setText(_translate("MainWindow", "ToDo:"))
|
||||||
|
|
||||||
|
# Befüllen der Arbeisschritttabelle mit Text
|
||||||
|
#item = self.ArbeitsschrittTable.
|
||||||
|
# Ein neues QTableWidgetItem erstellen und den Text setzen
|
||||||
|
item = QtWidgets.QTableWidgetItem("Auftrag laden")
|
||||||
|
self.ArbeitsschrittTable.setItem(0, 0, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem("--> Auftragsnummer eingeben \n--> \"load Auftrag\" Buttonclick")
|
||||||
|
self.ArbeitsschrittTable.setItem(0, 1, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem("Bauteiltyp erkennen")
|
||||||
|
self.ArbeitsschrittTable.setItem(1, 0, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem("visuell: \n--> ein Bauteil in die Kamera halten\n\nWaage: \n--> ein Bauteil auf die Waage legen\n--> \"Bauteiltyp erkennen\" Buttonclick\n\nmanuell:\n--> Bauteiltypen auswählen\n-->\"ckeck Waage\" Button click")
|
||||||
|
self.ArbeitsschrittTable.setItem(1, 1, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem("Bauteilanzahl erkennen")
|
||||||
|
self.ArbeitsschrittTable.setItem(2, 0, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem("--> Bauteile auflegen")
|
||||||
|
self.ArbeitsschrittTable.setItem(2, 1, item)
|
||||||
|
item = QtWidgets.QTableWidgetItem("Prozess beendet")
|
||||||
|
self.ArbeitsschrittTable.setItem(3, 0, item)
|
||||||
|
self.ArbeitsschrittTable.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers)
|
||||||
|
|
||||||
|
#self.ArbeitsschrittTable.item(0,0).setText("test")
|
||||||
|
|
||||||
|
#einzelteilID = int(self.AuftragsdetailsTable.item(i,0).text())
|
||||||
|
#self.PosNrTxtFeld.setText(str(self.AuftragsdetailsTable.item(i,0).text()))
|
||||||
|
#self.bauteiltypTextbox.setText(str(self.AuftragsdetailsTable.item(i,2).text()))
|
||||||
|
|
||||||
|
self.label.setText(_translate("MainWindow", "Auftragsnummer:"))
|
||||||
|
self.bauteilTypBtn.setText(_translate("MainWindow", "Bauteiltyp erkennen"))
|
||||||
|
self.bauteilTypBtn.clicked.connect(self.objectTypeDetection)
|
||||||
|
self.AuftragsdetailsTable.cellClicked.connect(self.onTableCellClick)
|
||||||
|
#self.AuftragsdetailsTable.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers)
|
||||||
|
#item = self.AuftragsdetailsTable.verticalHeaderItem(0)
|
||||||
|
#item.setText(_translate("MainWindow", "test"))
|
||||||
|
self.BezeichnungLabel.setText(_translate("MainWindow", "Bezeichnung"))
|
||||||
|
self.PosNrLabel.setText(_translate("MainWindow", "Pos.-Nr:"))
|
||||||
|
self.teileZuVielLabel.setText(_translate("MainWindow", "Zu prüfende Teileanzahl über Auftragsanzahl:"))
|
||||||
|
self.teileZuVielTxtFeld.setText(str(self.teileZuViel))
|
||||||
|
self.checkWaageBtn.setText(_translate("MainWindow", "check Waage"))
|
||||||
|
self.checkWaageBtn.clicked.connect(self.checkWaage)
|
||||||
|
self.stopLoopBtn.setText(_translate("MainWindow", "stop loop"))
|
||||||
|
self.stopLoopBtn.clicked.connect(self.stopLoopClicked)
|
||||||
|
self.waageTareBtn.setText(_translate("MainWindow", "Waage tarieren"))
|
||||||
|
self.waageTareBtn.clicked.connect(self.onTareClick)
|
||||||
|
self.checkBox.setText(_translate("MainWindow", "static workflow"))
|
||||||
|
self.checkBox.clicked.connect(self.onCheckboxCheck)
|
||||||
|
self.checkBoxAutoTare.setText(_translate("MainWindow", "automatisches Tarieren"))
|
||||||
|
self.checkBoxAutoTare.clicked.connect(self.autoTareCheck)
|
||||||
|
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 0,255,165,0) # zum setzen der ersten Spalte der Arbeitsschrittetabelle auf orange
|
||||||
|
self.checkBoxAutoTare.setCheckState(Qt.Checked)
|
||||||
|
self.checkBox.setCheckState(Qt.Unchecked)
|
||||||
|
|
||||||
|
def mousePressEvent(self, event):
|
||||||
|
print("Das MainWindow wurde angeklickt.")
|
||||||
|
self.setFocus()
|
||||||
|
super().mousePressEvent(event)
|
||||||
|
|
||||||
|
def onTareClick(self):
|
||||||
|
#Tarieren der Waage
|
||||||
|
if ser.is_open == False:
|
||||||
|
ser.open()
|
||||||
|
ser.write(b'tare\n')
|
||||||
|
ser.close()
|
||||||
|
|
||||||
|
def onCheckboxCheck(self):
|
||||||
|
if self.checkBox.isChecked() == True:
|
||||||
|
print("static workflow activated")
|
||||||
|
else:
|
||||||
|
print("static workflow deactivated")
|
||||||
|
|
||||||
|
def autoTareCheck(self):
|
||||||
|
if self.checkBoxAutoTare.isChecked() == True:
|
||||||
|
print("automatisches Tarieren ist aktiviert")
|
||||||
|
else:
|
||||||
|
print("automatisches Tarieren ist deaktiviert")
|
||||||
|
|
||||||
|
def getRowNr(self, posNr):
|
||||||
|
for i in range(0,self.AuftragsdetailsTable.rowCount()):
|
||||||
|
if(self.AuftragsdetailsTable.item(i,0).text() == str(posNr)):
|
||||||
|
return i
|
||||||
|
|
||||||
|
def onTableCellClick(self):
|
||||||
|
self.PosNrTxtFeld.setText(self.AuftragsdetailsTable.item(self.AuftragsdetailsTable.currentRow(),0).text())
|
||||||
|
self.bauteiltypTextbox.setText(self.AuftragsdetailsTable.item(self.AuftragsdetailsTable.currentRow(),2).text())
|
||||||
|
|
||||||
|
def setAuftragsnummer(self):
|
||||||
|
self.auftragsnummer = self.textEdit.toPlainText()
|
||||||
|
if(not self.auftragsnummer):
|
||||||
|
self.auftragsnummer = ""
|
||||||
|
self.textEdit.setText("")
|
||||||
|
|
||||||
|
def checkAuftragsnummerEmpty(self):
|
||||||
|
if self.auftragsnummer == "":
|
||||||
|
print("Das Auftragsnummernfeld ist leer.")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def checkPosNrEmpty(self):
|
||||||
|
if self.PosNrTxtFeld.toPlainText() == "":
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def updateGUI(self):
|
||||||
|
self.PosNrLabel.repaint() #GUI aktualisieren
|
||||||
|
QApplication.processEvents() #GUI aktualisieren
|
||||||
|
|
||||||
|
def setRowColor(self, tableObject, rowID,r,g,b):
|
||||||
|
# tableObject = das Tabellenobjekt, von welchem die Zeile gefärbt werden soll
|
||||||
|
# rowID = die Nr der Zeile, welche eingefärbt werden soll
|
||||||
|
# r,g,b = Farbe, welche die Zeile annehmen soll
|
||||||
|
|
||||||
|
# folgendes If-Statement hat ausschließlich einen Ästethischen Zweck -> und zwar, dass bei der Arbeitsschritttabelle lediglich die erste
|
||||||
|
# Spelte eingefärbt wird, anstatt beide Spalten
|
||||||
|
if tableObject == self.ArbeitsschrittTable:
|
||||||
|
nrColNoColor = 1
|
||||||
|
else:
|
||||||
|
nrColNoColor = 0
|
||||||
|
|
||||||
|
# Einfärben der Zellen einer Spalte
|
||||||
|
for col in range(tableObject.columnCount()-nrColNoColor):
|
||||||
|
tableObject.item(rowID, col).setBackground(QtGui.QColor(r,g,b))
|
||||||
|
|
||||||
|
def auftragsBtnClicked(self):
|
||||||
|
databaseQueryWorking = False #wird für die Überprüfung, ob die Datenbankabfrage fehlerhaft ist, verwendet
|
||||||
|
auftragEinzelteilDaten = []
|
||||||
|
|
||||||
|
self.setAuftragsnummer()
|
||||||
|
if(not self.checkAuftragsnummerEmpty()):
|
||||||
|
|
||||||
|
sql_query = "SELECT Auftraege.id, EinzelteilID, Auftragsnummer, Anzahl, Einzelteile.id, Bezeichnung, CAST(projectGeislinger.Einzelteile.GewichtMittelwert AS CHAR), CAST(projectGeislinger.Einzelteile.GewichtVarianz AS CHAR) FROM projectGeislinger.Auftraege, projectGeislinger.Einzelteile where projectGeislinger.Auftraege.EinzelteilID = projectGeislinger.Einzelteile.id AND projectGeislinger.Auftraege.Auftragsnummer = " + self.auftragsnummer
|
||||||
|
try:
|
||||||
|
cursor.execute(sql_query)
|
||||||
|
# Fetch results
|
||||||
|
auftragEinzelteilDaten = cursor.fetchall()
|
||||||
|
databaseQueryWorking = True
|
||||||
|
except:
|
||||||
|
print("Fehler in der Datenbankabfrage.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if databaseQueryWorking==True and len(auftragEinzelteilDaten)>0:
|
||||||
|
'''
|
||||||
|
# Display data
|
||||||
|
print("Ausgabe der Auftragsdetails des obigen Auftrags, inklusive Einzelteildetails:")
|
||||||
|
for row in auftragEinzelteilDaten:
|
||||||
|
if str(row[2]) == self.auftragsnummer:
|
||||||
|
print("passt")
|
||||||
|
print(row)
|
||||||
|
'''
|
||||||
|
|
||||||
|
### die Auftragsdaten in die Tabelle laden
|
||||||
|
self.AuftragsdetailsTable.setRowCount(len(auftragEinzelteilDaten))
|
||||||
|
self.item = QtWidgets.QTableWidgetItem()
|
||||||
|
counter = 0
|
||||||
|
for row in auftragEinzelteilDaten:
|
||||||
|
self.item = QtWidgets.QTableWidgetItem()
|
||||||
|
self.AuftragsdetailsTable.setItem(counter, 0, self.item)
|
||||||
|
self.item.setText(str(row[1]))
|
||||||
|
self.item.setFlags(self.item.flags() & ~QtCore.Qt.ItemIsEditable)
|
||||||
|
self.item = QtWidgets.QTableWidgetItem()
|
||||||
|
self.AuftragsdetailsTable.setItem(counter, 1, self.item)
|
||||||
|
self.item.setFlags(self.item.flags() & ~QtCore.Qt.ItemIsEditable)
|
||||||
|
self.item = QtWidgets.QTableWidgetItem()
|
||||||
|
self.AuftragsdetailsTable.setItem(counter, 2, self.item)
|
||||||
|
self.item.setText(str(row[5]))
|
||||||
|
self.item.setFlags(self.item.flags() & ~QtCore.Qt.ItemIsEditable)
|
||||||
|
self.item = QtWidgets.QTableWidgetItem()
|
||||||
|
self.AuftragsdetailsTable.setItem(counter, 3, self.item)
|
||||||
|
self.item.setText(str(row[3]))
|
||||||
|
self.item.setFlags(self.item.flags() & ~QtCore.Qt.ItemIsEditable)
|
||||||
|
self.item = QtWidgets.QTableWidgetItem()
|
||||||
|
self.AuftragsdetailsTable.setItem(counter, 4, self.item)
|
||||||
|
self.item.setText(str("0"))
|
||||||
|
self.item = QtWidgets.QTableWidgetItem()
|
||||||
|
self.AuftragsdetailsTable.setItem(counter, 5, self.item)
|
||||||
|
self.item.setFlags(self.item.flags() & ~QtCore.Qt.ItemIsEditable)
|
||||||
|
|
||||||
|
counter = counter +1
|
||||||
|
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 0,0,255,0) #zum setzen der ersten Zeile der Auftragstabelle auf grün
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 1,255,165,0) #zum setzen der zweiten Zeile der Auftragstabelle auf orange
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 2,255,255,255) #zum setzen der dritten Zeile der Auftragstabelle auf weiß
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 3,255,255,255) #zum setzen der vierten Zeile der Auftragstabelle auf weiß
|
||||||
|
|
||||||
|
# setzen der beiden Felder auf einen leeren String, um Fehler zu Vermeiden, wenn ein neuer Auftrag geladen wird
|
||||||
|
self.bauteiltypTextbox.setText("")
|
||||||
|
self.PosNrTxtFeld.setText("")
|
||||||
|
|
||||||
|
|
||||||
|
elif(databaseQueryWorking==True and len(auftragEinzelteilDaten)==0):
|
||||||
|
print("Es wurde in der Datenbank kein Auftrag mit dieser Auftragsnummer gefunden.")
|
||||||
|
|
||||||
|
def change_row_color(self, row, color_index):
|
||||||
|
if(color_index == 1):
|
||||||
|
self.setRowColor(self.AuftragsdetailsTable, row,255,255,255)
|
||||||
|
if(color_index == 2):
|
||||||
|
self.setRowColor(self.AuftragsdetailsTable, row,255,165,0)
|
||||||
|
if(color_index == 3):
|
||||||
|
self.setRowColor(self.AuftragsdetailsTable, row,0,255,0)
|
||||||
|
|
||||||
|
def stopLoopClicked(self):
|
||||||
|
# damit wird beim Klick auf den Stopbutton der stopLoop-boolWert in der Workerklasse auf true gesetzt -> der Stop des Threads wird initiiert
|
||||||
|
if hasattr(self, 'objectDetectionWorker'):
|
||||||
|
self.objectDetectionWorker.stopLoopSignal.emit(True)
|
||||||
|
|
||||||
|
if hasattr(self, 'checkWaageWorker'):
|
||||||
|
self.checkWaageWorker.stopLoopSignal.emit(True)
|
||||||
|
|
||||||
|
def checkFinished(self):
|
||||||
|
#die Funktion geht alle Zeilen der Auftragsliste durch und schaut, ob die richtige Anzahl an Teilen vorhanden sind
|
||||||
|
for i in range(0,self.AuftragsdetailsTable.rowCount()):
|
||||||
|
if self.AuftragsdetailsTable.item(i,3).text() != self.AuftragsdetailsTable.item(i,4).text():
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def checkWaage(self):
|
||||||
|
#print("Running in thread:", threading.current_thread().name) # Debuggingausgabe
|
||||||
|
QApplication.processEvents()
|
||||||
|
|
||||||
|
# die Loopvariable des Workers auf False setzten, damit die Schleife durchgelaufen wird (diese wird zum Abbruch der Schleife benötigt -> siehe stopLoop)
|
||||||
|
#self.checkWaageWorker.stopLoopSignal.emit(False)
|
||||||
|
|
||||||
|
# überprüfen, ob der Auftrag geladen wurde
|
||||||
|
if(self.AuftragsdetailsTable.item(0,0) == None):
|
||||||
|
print("Der Auftrag muss zuerst geladen werden.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# überprüfen, ob ein Bauteiltyp gesetzt wurde
|
||||||
|
if(self.checkPosNrEmpty()==True and self.checkBox.isChecked() == False):
|
||||||
|
print("Das Pos.-Nr.-Feld ist leer.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# den GUI Wert von Textfeld TeileZuViel in die Variable schreiben
|
||||||
|
self.teileZuViel = int(float(self.teileZuVielTxtFeld.toPlainText()))
|
||||||
|
self.teileZuVielTxtFeld.setText(str(self.teileZuViel))
|
||||||
|
|
||||||
|
einzelteilID = -1 # Initialisieren der Variable mit einem Defaultwert, welcher nie eingenommen werden können sollte
|
||||||
|
if (self.checkBox.isChecked() == False):
|
||||||
|
#übernehmen der BauteilID aus dem Feld Pos.-Nr - wenn der Workflow dynamisch gewählt wurde
|
||||||
|
einzelteilID = int(self.PosNrTxtFeld.toPlainText())
|
||||||
|
else:
|
||||||
|
# wenn der Workflow statisch gesetzt wurde, dann soll das erste Item aus der Auftragsliste geladen werden, von welchem noch nicht genug Bauteile auf der Waage liegen
|
||||||
|
for i in range(0,self.AuftragsdetailsTable.rowCount()):
|
||||||
|
if self.AuftragsdetailsTable.item(i,3).text() != self.AuftragsdetailsTable.item(i,4).text():
|
||||||
|
einzelteilID = int(self.AuftragsdetailsTable.item(i,0).text())
|
||||||
|
self.PosNrTxtFeld.setText(str(self.AuftragsdetailsTable.item(i,0).text()))
|
||||||
|
self.bauteiltypTextbox.setText(str(self.AuftragsdetailsTable.item(i,2).text()))
|
||||||
|
break
|
||||||
|
|
||||||
|
if einzelteilID == -1:
|
||||||
|
# den Thread beenden
|
||||||
|
self.checkWaageThread.quit()
|
||||||
|
self.checkWaageThread.wait()
|
||||||
|
try:
|
||||||
|
self.checkWaageThread.started.disconnect() # Trenne das Signal, damit es beim nächsten Start keine Konflikte gibt
|
||||||
|
print("Der Thread wurde beendet.")
|
||||||
|
except:
|
||||||
|
print("Disconnecting the thread did not work.")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
#zum setzen den Farbe der gesamten Reihe auf Orange
|
||||||
|
self.setRowColor(self.AuftragsdetailsTable, self.getRowNr(einzelteilID),255,165,0)
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 1,0,255,0) # zum setzen der zweiten Spalte der Arbeitsschrittetabelle auf grün
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 2,255,165,0) # zum setzen der dritten Spalte der Arbeitsschrittetabelle auf orange
|
||||||
|
|
||||||
|
# den Thread starten, welcher die Bauteilanzahl überprüft
|
||||||
|
self.checkWaageWorker = Worker()
|
||||||
|
self.checkWaageThread = QThread()
|
||||||
|
|
||||||
|
self.checkWaageWorker.moveToThread(self.checkWaageThread)
|
||||||
|
|
||||||
|
self.checkWaageWorker.checkWaageStartSignal.connect(self.checkWaageWorker.checkWaageThread)
|
||||||
|
self.checkWaageWorker.checkWaageUpdateSignal.connect(self.checkWaageUpdate)
|
||||||
|
self.checkWaageWorker.checkWaageFinishedSignal.connect(self.checkWaageFinished)
|
||||||
|
self.checkWaageWorker.waageStoppedSignal.connect(self.threadStopped)
|
||||||
|
self.checkWaageWorker.stopLoopSignal.connect(lambda status: setattr(self.checkWaageWorker, 'stopLoop', status)) #wird fürs aktive Stoppen des Threads benötigt
|
||||||
|
|
||||||
|
self.checkWaageThread.started.connect(lambda: self.checkWaageWorker.checkWaageStartSignal.emit(einzelteilID, self.teileZuViel, self.auftragsnummer))
|
||||||
|
self.checkWaageThread.start()
|
||||||
|
|
||||||
|
def checkWaageUpdate(self, einzelteilID, anzahl):
|
||||||
|
# die Funktion updated die (vom Thread) berechnete Bauteilanzahl in der GUI
|
||||||
|
self.AuftragsdetailsTable.item(self.getRowNr(einzelteilID), 4).setText(str(anzahl)) # in die Tabelle die Anzahl an berechneten Bauteilen reinschreiben
|
||||||
|
|
||||||
|
def checkWaageFinished(self, einzelteilID):
|
||||||
|
self.setRowColor(self.AuftragsdetailsTable, self.getRowNr(einzelteilID),0,255,0) #zum setzen den Farbe der gesamten Reihe auf Grün
|
||||||
|
|
||||||
|
if self.checkFinished(): # wenn alle Bauteile auf der Waage liegen, soll folgender Code ausgeführt werden
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 2,0,255,0) # zum setzen der dritten Spalte der Arbeitsschrittetabelle auf grün
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 3,0,255,0) # zum setzen der vierte Spalte der Arbeitsschrittetabelle auf grün
|
||||||
|
else: # wenn noch nicht alle Bauteile des Auftrags auf der Waage liegen, soll folgernder Code ausgeführt werden
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 1,255,165,0) # zum setzen der zweiten Spalte der Arbeitsschrittetabelle auf orange
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 2,255,255,255) # zum setzen der dritten Spalte der Arbeitsschrittetabelle auf weiß
|
||||||
|
if self.checkBoxAutoTare.isChecked():
|
||||||
|
self.onTareClick()
|
||||||
|
|
||||||
|
# den Thread beenden
|
||||||
|
self.checkWaageThread.quit()
|
||||||
|
self.checkWaageThread.wait()
|
||||||
|
|
||||||
|
# auch wenn die Länge der Liste überschritten wurde
|
||||||
|
# wenn der statische Workflow aktiviert ist, dann soll die checkwaage-funktion erneut aufgerufen werden
|
||||||
|
if(self.checkBox.isChecked() == True):
|
||||||
|
self.checkWaage()
|
||||||
|
|
||||||
|
# GUI updaten
|
||||||
|
#self.updateGUI()
|
||||||
|
|
||||||
|
def objectTypeDetection(self):
|
||||||
|
# in dieser Funktion wird der Typ des Bauteils automatisch erkannt
|
||||||
|
|
||||||
|
# wenn der statische Workflow ausgewählt wurde, dann soll die checkWaage Funktion aufgerufen werden, auch wenn die detectBauteiltyp-Funkion aufgerufen wurde
|
||||||
|
if self.checkBox.isChecked() == True:
|
||||||
|
self.checkWaage()
|
||||||
|
return
|
||||||
|
|
||||||
|
'''
|
||||||
|
if(self.checkPosNrEmpty()==True):
|
||||||
|
print("Das Pos.-Nr.-Feld ist leer.")
|
||||||
|
return
|
||||||
|
'''
|
||||||
|
|
||||||
|
# die Loopvariable des Workers auf False setzten, damit die Schleife durchgelaufen wird (diese wird zum Abbruch der Schleife benötigt -> siehe stopLoop)
|
||||||
|
#self.objectDetectionWorker.stopLoopSignal.emit(False)
|
||||||
|
|
||||||
|
# überprüfen, ob der Auftrag in die Tabelle geladen wurde
|
||||||
|
if(self.AuftragsdetailsTable.item(0,0) == None):
|
||||||
|
print("Der Auftrag muss zuerst geladen werden.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# speichert den Wert, welcher im Textfeld steht in Variablen im Code
|
||||||
|
self.setAuftragsnummer()
|
||||||
|
|
||||||
|
# starten des Threats, welcher den Bauteiltyp zurück gibt
|
||||||
|
self.objectDetectionWorker = Worker()
|
||||||
|
self.objectDetectionThread = QThread()
|
||||||
|
|
||||||
|
self.objectDetectionWorker.moveToThread(self.objectDetectionThread)
|
||||||
|
|
||||||
|
self.objectDetectionWorker.objectDetectionStartSignal.connect(self.objectDetectionWorker.objectTypeDetectionThread)
|
||||||
|
self.objectDetectionWorker.objectDetectionFinishedSignal.connect(self.objectTypeDetectionFinished)
|
||||||
|
self.objectDetectionWorker.waageStoppedSignal.connect(self.threadStopped)
|
||||||
|
self.objectDetectionWorker.stopLoopSignal.connect(lambda status: setattr(self.objectDetectionWorker, 'stopLoop', status)) #wird fürs aktive Stoppen des Threads benötigt
|
||||||
|
|
||||||
|
self.objectDetectionThread.started.connect(lambda: self.objectDetectionWorker.objectDetectionStartSignal.emit(self.auftragsnummer))
|
||||||
|
self.objectDetectionThread.start()
|
||||||
|
|
||||||
|
def objectTypeDetectionFinished(self, einzelteilID, rowData):
|
||||||
|
# wenn der Typ des Objektes erkannt wurde, dann soll die Funktion aufgerufen werden
|
||||||
|
|
||||||
|
# Schreiben der Bauteiltype und Pos.-Nr in die jeweiligen Felder
|
||||||
|
self.PosNrTxtFeld.setText(str(rowData[1]))
|
||||||
|
self.bauteiltypTextbox.setText(rowData[2])
|
||||||
|
|
||||||
|
# setzt den Boolean, um aus der Schleife raus zu gehen
|
||||||
|
self.btTypeIsSet = True
|
||||||
|
|
||||||
|
#zum setzen den Farbe der gesamten Reihe auf Orange
|
||||||
|
self.setRowColor(self.AuftragsdetailsTable, self.getRowNr(einzelteilID),255,165,0)
|
||||||
|
|
||||||
|
# den Thread beenden
|
||||||
|
self.objectDetectionThread.quit()
|
||||||
|
self.objectDetectionThread.wait()
|
||||||
|
|
||||||
|
# wenn der Bauteiltyp erkannt wurde, dann soll die GUI aktualisiert werden und anschließend die CheckWaage-Funktion aufgerufen werden
|
||||||
|
self.updateGUI()
|
||||||
|
self.checkWaage()
|
||||||
|
|
||||||
|
def threadStopped(self, einzelteilID):
|
||||||
|
# wenn kein Bauteil erkannt wurde, dann ist die EinzenteilID = 0
|
||||||
|
if self.checkFinished() == False:
|
||||||
|
if(einzelteilID > 0):
|
||||||
|
self.setRowColor(self.AuftragsdetailsTable, self.getRowNr(einzelteilID),255,255,255) #zum setzen den Farbe der gesamten Reihe auf Weiß
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 2,255,255,255)
|
||||||
|
self.setRowColor(self.ArbeitsschrittTable, 1,255,165,0)
|
||||||
|
|
||||||
|
# den Thread beenden
|
||||||
|
if hasattr(self, 'objectDetectionThread'):
|
||||||
|
self.objectDetectionThread.quit()
|
||||||
|
self.objectDetectionThread.wait()
|
||||||
|
print("Der ObjektDetection-Thread wurde beendet.")
|
||||||
|
|
||||||
|
if hasattr(self, 'checkWaageThread'):
|
||||||
|
self.checkWaageThread.quit()
|
||||||
|
self.checkWaageThread.wait()
|
||||||
|
print("Der CheckWaage-Thread wurde beendet.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
MainWindow = QtWidgets.QMainWindow()
|
||||||
|
ui = Ui_MainWindow()
|
||||||
|
ui.setupUi(MainWindow)
|
||||||
|
MainWindow.show()
|
||||||
|
sys.exit(app.exec_())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user