Ich rufe in meinem init.py verschiede Threads auf. Ein Thread soll eine TCP Verbindung zwischen einer SPS und meinem Computer herstellen. Diese Funktion wird in KM.py aufgerufen. Wenn nun als Telegramm Einlesen_d_0? kommt soll eine Funktion im init.py ausgeführt werden. Zum Verständis: Es soll ein Rubix Cube eingelesen werden. Das funktioniert auch schon mit einem Button der im __init__.py aufgerufen wird. Wie ich es jetzt aber schaffe aus dem KM.py die Take_Site_0 richtig auszuführen erschließt sich mir nicht. Er kommt immer nur bis zum Debug_3 und kommt dann nicht weiter. Es erscheint auch keine Fehlermeldung.
KM.py vereinfacht:
from __init__ import test
def RecvConnection():
while 1:
try:
if not InitDone:
time.sleep(5)
print("test")
else:
recvData = TCPconnection.recv()
print(recvData)
if recvData == "Einlesen_d_0?":
print ("Debug1")
Site0Detection()
except:
time.sleep(1)
def Site0Detection():
test()
TCPconnection.send("Einlesen_d_0!")
print("KM - Seite 0 einlesen erfolgreich")
__init__.py vereinfacht:
import KM
class opencvGUI:
def Take_Site_0(self):
print ("Take Site 0")
self.openCV.getSquareCol(self.openCV.frame)
print ("Debug2")
Cube.Take_Site_0(self.openCV)
self.update()
def test():
print ("Debug3")
window.Take_Site_0()
print ("Debug4")
if __name__ == '__main__':
global Debug
# Debug False/True
Debug = True
# Create CubeMatrix
Cube = Cube.CubeClass()
# Open QApplication
app=QApplication(sys.argv)
window=opencvGUI()
window.setWindowTitle('RobixSolver')
window.show()
# Daemon-Threat (KM)
KMthreadInit = threading.Thread(name='KMdaemonInit', target=KM.InitConnection)
KMthreadInit.setDaemon(True)
KMthreadInit.start()
KMthreadSend = threading.Thread(name='KMdaemonSend', target=KM.SendConnection)
KMthreadSend.setDaemon(True)
KMthreadSend.start()
KMthreadRecv = threading.Thread(name='KMdaemonRecv', target=KM.RecvConnection)
KMthreadRecv.setDaemon(True)
KMthreadRecv.start()
Funktionen richtig aus einem Thread aufrufen
Das `from __init__` ist falsch. Man importiert das Paket mit seinem Namen, dann wird automatisch __init__.py importiert.
Funktionen schreibt man wie Variablennamen komplett klein. Das selbe gilt für Module.
Es gibt True um eine Endlosschleife zu schreiben, nicht 1.
`RecvConnection` benutzt eine unmenge undefinierter Variablen, alles was eine Funktion braucht, muß sie als Argumente bekommen.
Da sich InitDone innerhalb der Schleife nicht ändert, macht das irgendwie keinen Sinn. Für Threads muß man mit entsprechenden Mechanismen arbeiten, hier wahrscheinlich einem Lock, das vor der Schleife so lange wartet, bis es die Initialisierung fertig ist (bzw. warum startest Du den Thread nicht erst nach der Initialisierung?)
Was ist `TCPconnection` für ein Objekt? Ein recv ohne Argument?
`Site0Detection` ruft `test` auf, was wiederum Irgendetwas mit einem Fenster macht. Das darf man nicht. Fenster dürfen nur aus dem Hauptthread heraus geändert werden. Da Du anscheinend Qt benutzt, löst man solche Probleme mit QThreads und Signalen.
Wie schon geschrieben, globale Variablen darf man nicht benutzten. Aber ein `global` außerhalb einer Funktion macht zudem noch nicht einmal Sinn.
Cube wird durch ein Cube.CubeClass-Instanz überschrieben. Das ist sehr fehleranfällig und würde auch zu einem Fehler führen, wenn alles was im if-__name__-Block steht in einer Funktion main stehen würde. Und diese main-Funktion ist auch dringend nötig, damit man nicht globale Variablen erzeugt und diese aus Versehen auch noch nutzt.
Du mußt also drei Schritte machen:
1. richtige Funktionen schreiben, die keine globalen Variablen benutzen.
2. QThreads verwenden
3. Das Fenster nicht aus dem Thread heraus verändern, sondern Signale benutzen.
Funktionen schreibt man wie Variablennamen komplett klein. Das selbe gilt für Module.
Es gibt True um eine Endlosschleife zu schreiben, nicht 1.
`RecvConnection` benutzt eine unmenge undefinierter Variablen, alles was eine Funktion braucht, muß sie als Argumente bekommen.
Da sich InitDone innerhalb der Schleife nicht ändert, macht das irgendwie keinen Sinn. Für Threads muß man mit entsprechenden Mechanismen arbeiten, hier wahrscheinlich einem Lock, das vor der Schleife so lange wartet, bis es die Initialisierung fertig ist (bzw. warum startest Du den Thread nicht erst nach der Initialisierung?)
Was ist `TCPconnection` für ein Objekt? Ein recv ohne Argument?
`Site0Detection` ruft `test` auf, was wiederum Irgendetwas mit einem Fenster macht. Das darf man nicht. Fenster dürfen nur aus dem Hauptthread heraus geändert werden. Da Du anscheinend Qt benutzt, löst man solche Probleme mit QThreads und Signalen.
Wie schon geschrieben, globale Variablen darf man nicht benutzten. Aber ein `global` außerhalb einer Funktion macht zudem noch nicht einmal Sinn.
Cube wird durch ein Cube.CubeClass-Instanz überschrieben. Das ist sehr fehleranfällig und würde auch zu einem Fehler führen, wenn alles was im if-__name__-Block steht in einer Funktion main stehen würde. Und diese main-Funktion ist auch dringend nötig, damit man nicht globale Variablen erzeugt und diese aus Versehen auch noch nutzt.
Du mußt also drei Schritte machen:
1. richtige Funktionen schreiben, die keine globalen Variablen benutzen.
2. QThreads verwenden
3. Das Fenster nicht aus dem Thread heraus verändern, sondern Signale benutzen.
Danke für die schnelle Antwort!
"Das `from __init__` ist falsch. Man importiert das Paket mit seinem Namen, dann wird automatisch __init__.py importiert."
Wie muss es dann heißen? from init import test?
Funktionen schreibt man wie Variablennamen komplett klein. Das selbe gilt für Module.
Es gibt True um eine Endlosschleife zu schreiben, nicht 1.
-> okay
`RecvConnection` benutzt eine unmenge undefinierter Variablen, alles was eine Funktion braucht, muß sie als Argumente bekommen.
Da sich InitDone innerhalb der Schleife nicht ändert, macht das irgendwie keinen Sinn.
-> Diese werden in einer Anderen Funktion aufgerufen. Diese habe ich zur Übersichtlichkeit nicht hier rein geschrieben. Da die Verbindung funktioniert
def InitConnection():
global TCPconnection
global InitDone
TCPconnection = ConnManager('*.*.*.*', ****)
InitDone = True
Für Threads muß man mit entsprechenden Mechanismen arbeiten, hier wahrscheinlich einem Lock, das vor der Schleife so lange wartet, bis es die Initialisierung fertig ist (bzw. warum startest Du den Thread nicht erst nach der Initialisierung?)
Ich habe noch keine Erfahrung mit hochsprachen gemacht. Bin sehr SPS belastet. Das war einfach die einfachste Lösung für mich. Ich springe solange drüber bis die Initalisierung fertig ist.
Was ist `TCPconnection` für ein Objekt? Ein recv ohne Argument?
`Site0Detection` ruft `test` auf, was wiederum Irgendetwas mit einem Fenster macht. Das darf man nicht. Fenster dürfen nur aus dem Hauptthread heraus geändert werden. Da Du anscheinend Qt benutzt, löst man solche Probleme mit QThreads und Signalen.
Es wird in dem Fenster die Farben geändert. Ich lese mir also die Farben des Cubs aus und zeige sie visuell an. Okay schau ich mir an
Wie schon geschrieben, globale Variablen darf man nicht benutzten. Aber ein `global` außerhalb einer Funktion macht zudem noch nicht einmal Sinn.
Cube wird durch ein Cube.CubeClass-Instanz überschrieben. Das ist sehr fehleranfällig und würde auch zu einem Fehler führen, wenn alles was im if-__name__-Block steht in einer Funktion main stehen würde. Und diese main-Funktion ist auch dringend nötig, damit man nicht globale Variablen erzeugt und diese aus Versehen auch noch nutzt.
Okay
"Das `from __init__` ist falsch. Man importiert das Paket mit seinem Namen, dann wird automatisch __init__.py importiert."
Wie muss es dann heißen? from init import test?
Funktionen schreibt man wie Variablennamen komplett klein. Das selbe gilt für Module.
Es gibt True um eine Endlosschleife zu schreiben, nicht 1.
-> okay

`RecvConnection` benutzt eine unmenge undefinierter Variablen, alles was eine Funktion braucht, muß sie als Argumente bekommen.
Da sich InitDone innerhalb der Schleife nicht ändert, macht das irgendwie keinen Sinn.
-> Diese werden in einer Anderen Funktion aufgerufen. Diese habe ich zur Übersichtlichkeit nicht hier rein geschrieben. Da die Verbindung funktioniert

def InitConnection():
global TCPconnection
global InitDone
TCPconnection = ConnManager('*.*.*.*', ****)
InitDone = True
Für Threads muß man mit entsprechenden Mechanismen arbeiten, hier wahrscheinlich einem Lock, das vor der Schleife so lange wartet, bis es die Initialisierung fertig ist (bzw. warum startest Du den Thread nicht erst nach der Initialisierung?)
Ich habe noch keine Erfahrung mit hochsprachen gemacht. Bin sehr SPS belastet. Das war einfach die einfachste Lösung für mich. Ich springe solange drüber bis die Initalisierung fertig ist.
Was ist `TCPconnection` für ein Objekt? Ein recv ohne Argument?
`Site0Detection` ruft `test` auf, was wiederum Irgendetwas mit einem Fenster macht. Das darf man nicht. Fenster dürfen nur aus dem Hauptthread heraus geändert werden. Da Du anscheinend Qt benutzt, löst man solche Probleme mit QThreads und Signalen.
Es wird in dem Fenster die Farben geändert. Ich lese mir also die Farben des Cubs aus und zeige sie visuell an. Okay schau ich mir an
Wie schon geschrieben, globale Variablen darf man nicht benutzten. Aber ein `global` außerhalb einer Funktion macht zudem noch nicht einmal Sinn.
Cube wird durch ein Cube.CubeClass-Instanz überschrieben. Das ist sehr fehleranfällig und würde auch zu einem Fehler führen, wenn alles was im if-__name__-Block steht in einer Funktion main stehen würde. Und diese main-Funktion ist auch dringend nötig, damit man nicht globale Variablen erzeugt und diese aus Versehen auch noch nutzt.
Okay

Wenn Du meinen Beitrag zitierst, benutze bitte die Zitierfunktion hier im Forum.
Bei Dir ist das aber ja schon der Fall, weil Dein Programm läuft ja nicht.
Es muß so heißen, wie Du Dein Paket genannt hast. Ich hoffe mal, das heißt nicht init, denn das wäre ein sehr generischer Name.FloKnoe hat geschrieben: Donnerstag 18. Februar 2021, 11:46Wie muss es dann heißen? from init import test?
"Funktionieren" ist ein weites Feld. Gerade bei Threads scheint etwas keinen Fehler zu machen, aber es funktioniert noch lange nicht, das Programm ist nur unglücklicherweise noch nicht abgestürzt. Unglücklicherweise deshalb, weil dann wüßte man, dass das Programm fehlerhaft ist.FloKnoe hat geschrieben: Donnerstag 18. Februar 2021, 11:46-> Diese werden in einer Anderen Funktion aufgerufen. Diese habe ich zur Übersichtlichkeit nicht hier rein geschrieben. Da die Verbindung funktioniert
Bei Dir ist das aber ja schon der Fall, weil Dein Programm läuft ja nicht.
Das ist keine Thema von Hochsprachen, sondern ein sehr spezielles Thema mit Threads. Moderne Sprachen erlauben oft keinen geteilten Zustand zwischen mehreren Threads, weil das immer ein Programmierfehler ist. Leider hilft einem da Python nicht. Man muß also sich selbst in das Thema Threads einlernen, und vor allem alle Dont`s beachten: Benutze keinen geteilten Zustand zwischen Threads, sondern nutze immer Mechanismen, die genau dafür gemacht sind, Informationen von einem Thread in den anderen zu übertragen. Das sind Locks, Mutex, Semaphore, Queues und bei Qt eben auch Signale.FloKnoe hat geschrieben: Donnerstag 18. Februar 2021, 11:46Ich habe noch keine Erfahrung mit hochsprachen gemacht. Bin sehr SPS belastet. Das war einfach die einfachste Lösung für mich. Ich springe solange drüber bis die Initalisierung fertig ist.