Seite 1 von 1

QTimer Verständnisproblem

Verfasst: Montag 19. Oktober 2020, 15:22
von caargoo
Hallo zusammen,
ich möchte einen String von einem Mikrocontroller in einer sehr einfachen GUI Anwendung(nur ein Label) angezeigt bekommen.

Code: Alles auswählen

import sys
import PyQt5.QtCore as core
import PyQt5.QtWidgets as widgets
import PyQt5.QtGui as gui
import PyQt5.uic as uic
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtCore import QObject, QTimer
import time
import serial

timer = QTimer()
app = widgets.QApplication(sys.argv) 
win = uic.loadUi("AM2320.ui")

def msgButtonClick():
	pass

def SerialFehler():
	msg = QMessageBox()
	msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
	msg.setIcon(QMessageBox.Critical)
	msg.setWindowTitle("FEHLER!")
	msg.setText("COM nicht vorhanden!")
	msg.setInformativeText("Kann nicht verbinden!")
	msg.setStandardButtons(QMessageBox.Ok)
	msg.buttonClicked.connect(msgButtonClick)
	returnValue = msg.exec()
	if returnValue == QMessageBox.Ok:
		exit()
				
try:
	ser = serial.Serial('COM11',19200, timeout=1)
	ser.close()
	win.statusBar.showMessage(ser.name + " VERBUNDEN") #STATUSBAR!!!!
	
except serial.serialutil.SerialException:
	win.statusBar.showMessage(">> COM NICHT VERBUNDEN! <<") #STATUSBAR!!!! 
	SerialFehler()
	
	
def einlesen():
	if ser.is_open:
		ser.close()
		
	ser.open()
	x = ser.in_waiting
	
	if x >  0:
		s = ser.read(x)
		print(s)
		s = str(s)
		print(s)
		print(s.rfind("F"))
		n = (s.rfind("F"))
		if n == 2:
			win.label_1.setText(s[3:8])
			
		if n == 3:
			win.label_2.setText(s[4:9])
			
		ser.close()

		
timer.timeout.connect(einlesen)
timer.start(1000) 
print(timer.isActive())

win.show()
sys.exit(app.exec_())
Timer.isActive = True, aber er springt nicht nach einlesen().
Kann mir bitte jemand auf die Sprünge helfen?

Re: QTimer Verständnisproblem

Verfasst: Montag 19. Oktober 2020, 15:34
von __deets__
Woher weißt du, dass er nicht in einlesen einspringt? Ich sehe da keine Ausgabe, die das belegen würde. Was auf jeden Fall *nicht* so geht wie du das zu erwarten scheinst: das serielle Daten gepuffert werden, auch wenn kein Gerät geöffnet ist. Das passiert so nicht. Der Kernel hätte sonst eine Menge nutzloser Daten aufzubewahren. Du musst die Verbindung geöffnet halten, und dann später im Timer damit arbeiten. Wozu auch die Verwendung von Objekten anzuraten ist, denn so hantierst du mit globalen Variablen, und die sind boese(tm).

Re: QTimer Verständnisproblem

Verfasst: Montag 19. Oktober 2020, 16:53
von __blackjack__
@caargoo: Eingerückt wird in Python mit vier Leerzeichen pro Ebene, nicht mit Tabs.

Du öffnest eine serielle Verbindung und schliesst sie sofort wieder und informierst den Benutzer dann darüber, dass er Verbunden ist, obwohl er das nach dem `close()` ja gar nicht ist‽

Von der GUI heraus sollte man nicht `sys.exit()` aufrufen. Damit umgeht man den von Qt vorgesehenen Weg eine GUI-Anwendung ordentlich zu beenden. Da sollte man `quit()` auf dem Qt-Anwendungsobjekt aufrufen, damit am Ende dann auch tatsächlich der Punkt erreicht wird, wo das `sys.exit()` in der letzten Zeile ausgeführt wird.

Re: QTimer Verständnisproblem

Verfasst: Montag 19. Oktober 2020, 16:53
von Sirius3
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, keine Tabs.
`ser.is_open` ist eine Funktion und damit immer wahr. Das close wird also immer ausgeführt. Was auch nicht weiter schlimm ist, aber das if ist überflüssig.
`ser.in_waiting` ist auch eine Funktion, die kann aber nie größer als 1 sein, weil ein Vergleich einer Funktion mit einer Zahl keinen Sinn ergibt.
`x` wäre für eine ganze Zahl auch ein falscher Name, weil man mit x eine Kommazahl verbindet.
Dann sind natürlich die ganzen globalen Variablen schlecht, weil man im ganzen Code nicht durchblickt. Für GUIs braucht man zwangsläufig Klassendefinitionen.

Re: QTimer Verständnisproblem

Verfasst: Montag 19. Oktober 2020, 17:40
von __blackjack__
`is_open` und `in_waiting` sind beides Attribute. Letzteres ein Property, aber das ist ja letztlich ein Implementierungsdetail. Die alte API hatte `isOpen()` und `inWaiting()` als Methoden.

Re: QTimer Verständnisproblem

Verfasst: Dienstag 20. Oktober 2020, 15:05
von caargoo
Danke für die zahlreichen Antworten.
Fürs erste funktionierts soweit. Hab mich mit ser.open und close selbst in die Irre geführt.
Die Einrückungen waren in der IDE(Wing) auf Tabs gestellt, habs korrigiert.
@Sirius3: Das mit in_waiting funktioniert aber. Ich schicke 2 Strings, einmal mit 8Zeichen und
einmal mit 9Zeichen, dementsprechend ist x entweder 8 oder 9. Viel größer wird das Progrämmchen
nicht, nur ein zweites Label kommt noch hinzu.
Alle anderen nützlichen Hinweise werde ich versuchen nach und nach umzusetzen.