# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'test.ui' # # Created by: PyQt5 UI code generator 5.15.9 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. ##########Es muss noch überprüft werden, ob der PC mit der Waage überhaupt verbunden ist #from PyQt5 import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QProgressBar from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import QApplication from PyQt5.QtCore import QTimer, QThread, pyqtSignal, QObject 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) waageEingeschwungen = False def wahrscheinlichkeitsDichte(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 calcWahrscheinlichkeitFromDichte(x,mue, var): # in der Funktion wird die Wahrscheinlichkeit via der Wahrscheinlichkeitsdichte berechnet, indem das Verhältnis aus der dem Bauteil zugehörigen Wahrscheinlichkeitsdichte zu der maximalen Wahrscheinlichkeitsdichte berechnet wird p1 = wahrscheinlichkeitsDichte(x,mue, var) p_max = wahrscheinlichkeitsDichte(mue,mue, var) return p1/p_max #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 def __init__(self): super(Worker, self).__init__() stopLoop = False 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 waageEingeschwungen = True else: print("die Waage ist noch nicht eingeschwungen") 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 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 waageEingeschwungen, intString = self.readWaage() if 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([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 = 0 anzahl = 0 einzelteilID = einzelteilID while (self.correctBtNr == False and self.stopLoop == False): #überprüfen, ob die Waage eingeschwungen ist (und damit korrekte Ergebnisse liefert) waageEingeschwungen, intString = self.readWaage() if 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): # 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 varGes = float(articleData[7])*i # Berechnen der äquivalenten Varianz propDensVect.append([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 = 0 # 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(1090, 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") self.AuftragsdetailsTable = QtWidgets.QTableWidget(self.centralwidget) self.AuftragsdetailsTable.setGeometry(QtCore.QRect(10, 300, 661, 192)) 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) 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, 150, 161, 25)) self.bauteilTypBtn.setObjectName("bauteilTypBtn") self.checkWaageBtn = QtWidgets.QPushButton(self.centralwidget) self.checkWaageBtn.setGeometry(QtCore.QRect(700, 460, 161, 25)) self.checkWaageBtn.setObjectName("checkWaageBtn") self.stopLoopBtn = QtWidgets.QPushButton(self.centralwidget) self.stopLoopBtn.setGeometry(QtCore.QRect(700, 500, 161, 25)) self.stopLoopBtn.setObjectName("stopLoopBtn") self.waageTareBtn = QtWidgets.QPushButton(self.centralwidget) self.waageTareBtn.setGeometry(QtCore.QRect(700, 100, 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.BezeichnungLabel.setObjectName("BezeichnungLabel") self.teileZuVielLabel = QtWidgets.QLabel(self.centralwidget) self.teileZuVielLabel.setGeometry(QtCore.QRect(700, 350, 350, 17)) self.teileZuVielLabel.setObjectName("teileZuVielLabel") self.teileZuVielTxtFeld = QtWidgets.QTextEdit(self.centralwidget) self.teileZuVielTxtFeld.setGeometry(QtCore.QRect(700, 370, 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) ''' item = QtWidgets.QTableWidgetItem() font = QtGui.QFont() font.setPointSize(8) item.setFont(font) self.AuftragsdetailsTable.setVerticalHeaderItem(0,item) ''' 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) 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")) 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.thread = QThread() self.worker = Worker() self.worker.moveToThread(self.thread) self.worker.objectDetectionFinishedSignal.connect(self.objectTypeDetectionFinished) self.worker.waageStoppedSignal.connect(self.threadStopped) self.worker.stopLoopSignal.connect(lambda status: setattr(self.worker, 'stopLoop', status)) 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("clickedCheckboxTrue") else: print("clickedCheckboxFalse") def getRowNr(self, posNr): for i in range(0,self.AuftragsdetailsTable.rowCount()): if(self.AuftragsdetailsTable.item(i,0).text() == str(posNr)): return i # brauche ich hier vermutlich nicht mehr - ist in den Worker Thread kopiert worden def waageNichtEingeschwungenOutput(self): print("Die Waage ist noch nicht eingeschwungen - Ergebnisse sind dadurch noch fehlerhaft.") 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 # eventuell benötigt man die Funktion hier nicht mehr, da sie zu den Threads kopiert wurde 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 updateGUI(self): self.PosNrLabel.repaint() #GUI aktualisieren QApplication.processEvents() #GUI aktualisieren def setRowColor(self, rowID,r,g,b): self.AuftragsdetailsTable.item(rowID, 0).setBackground(QtGui.QColor(r,g,b)) self.AuftragsdetailsTable.item(rowID, 1).setBackground(QtGui.QColor(r,g,b)) self.AuftragsdetailsTable.item(rowID, 2).setBackground(QtGui.QColor(r,g,b)) self.AuftragsdetailsTable.item(rowID, 3).setBackground(QtGui.QColor(r,g,b)) self.AuftragsdetailsTable.item(rowID, 4).setBackground(QtGui.QColor(r,g,b)) self.AuftragsdetailsTable.item(rowID, 5).setBackground(QtGui.QColor(r,g,b)) #wird hier vermutlich nicht mehr benötigt - wurde in die Workerklasse kopiert 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 self.checkPosNrEmpty() 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 waageEingeschwungen = True else: print("die Waage ist noch nicht eingeschwungen") 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 waageEingeschwungen, intString 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 elif(databaseQueryWorking==True and len(auftragEinzelteilDaten)==0): print("Es wurde in der Datenbank kein Auftrag mit dieser Auftragsnummer gefunden.") 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 self.worker.stopLoopSignal.emit(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.worker.stopLoopSignal.emit(False) # überprüfen, ob ein Bauteiltyp gesetzt wurde if(self.checkPosNrEmpty()==True): print("Das Pos.-Nr.-Feld ist leer.") return if(self.AuftragsdetailsTable.item(0,0) == None): print("Der Auftrag muss zuerst geladen werden.") return # den GUI Wert von Textfeld TeileZuViel in die Variable schreiben self.teileZuViel = int(float(self.teileZuVielTxtFeld.toPlainText())) self.teileZuVielTxtFeld.setText(str(self.teileZuViel)) #übernehmen der BauteilID aus dem Feld Pos.-Nr einzelteilID = int(self.PosNrTxtFeld.toPlainText()) #zum setzen den Farbe der gesamten Reihe auf Orange self.setRowColor(self.getRowNr(einzelteilID),255,165,0) # den Thread starten, welcher die Bauteilanzahl überprüft self.worker.checkWaageStartSignal.connect(self.worker.checkWaageThread) self.worker.checkWaageUpdateSignal.connect(self.checkWaageUpdate) self.worker.checkWaageFinishedSignal.connect(self.checkWaageFinished) self.thread.started.connect(lambda: self.worker.checkWaageStartSignal.emit(einzelteilID, self.teileZuViel, self.auftragsnummer)) self.thread.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.getRowNr(einzelteilID),0,255,0) #zum setzen den Farbe der gesamten Reihe auf Grün # den Thread beenden self.thread.quit() self.thread.wait() try: self.thread.started.disconnect(lambda: self.worker.checkWaageStartSignal.emit(einzelteilID, self.teileZuViel, self.auftragsnummer)) # 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.") # Trenne das Signal, damit es beim nächsten Start keine Konflikte gibt # GUI updaten #self.updateGUI() def objectTypeDetection(self): # in dieser Funktion wird der Typ des Bauteils automatisch erkannt ''' 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.worker.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.worker.objectDetectionStartSignal.connect(self.worker.objectTypeDetectionThread) self.thread.started.connect(lambda: self.worker.objectDetectionStartSignal.emit(self.auftragsnummer)) self.thread.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.getRowNr(einzelteilID),255,165,0) # den Thread beenden self.thread.quit() self.thread.wait() try: self.thread.started.disconnect() # Trenne das Signal, damit es beim nächsten Start keine Konflikte gibt except: print("Disconnecting the thread did not work.") # 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(einzelteilID > 0): self.setRowColor(self.getRowNr(einzelteilID),255,255,255) #zum setzen den Farbe der gesamten Reihe auf Weiß # den Thread beenden self.thread.quit() self.thread.wait() try: self.thread.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.") 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_())