Seite 1 von 1
einer abgeleiteten Klasse in einem Thread eine Queue mitgeben
Verfasst: Donnerstag 2. März 2017, 19:05
von XCDRiVER
Hallo Leute,
ich scheitere an dem Punkt, dem Server-thread meine Queue q mitzugeben. Problem in Zeile 34.
die __init__ gehört zum Originalbeispiel nicht dazu, die habe ich reingebastelt, ich vermute aber so in dieses Richtung müsste man das machen?
Wie gesagt, ich finde einfach keinen Weg die Queue beim erstellen mitzugeben.
mein Ziel: Ich möchte eigentlich nur die empfangenen Daten des UDP-Server (data) aus der Klasse 'MyUdpHandler' an die Klasse 'mainWindow' weiterreichen.
Aber ich finde nicht raus wie ich diese Queue hier reinbauen muss. Was hab ich hier nur wieder nicht richtig gemacht?
Code: Alles auswählen
#socketserverUDP von docs.python.org
from socketserver import BaseRequestHandler, UDPServer
from threading import Thread
from queue import Queue, Empty
from tkinter import Tk, Label
class MyUdpHandler(BaseRequestHandler):
def __init__(self, request, client_address, server, myQueue):
BaseRequestHandler.__init__(self, request, client_address, server)
self.q = myQueue
pass
def handle(self):
self.data = self.request[0].strip()
## socket = self.request[1]
print("[{}] - {} - {}".format(self.client_address[0], self.client_address[1], self.data.decode()))
class mainWindow(Tk):
def __init__(self, q):
self.q = q
Tk.__init__(self)
self.labelData = Label(self, text='-----')
self.labelData.pack()
self.mainloop()
if __name__ == "__main__":
q = Queue()
## Serverstart als eigener Thread ------------------------------------
HOST, PORT = "", 51456
server = UDPServer((HOST, PORT), MyUdpHandler)
serverThread = Thread(target=server.serve_forever, myQueue=(q))
serverThread.start()
## Ende Serverstart
## Starte Fenster ----------------------------------------------------
mainWindowThread = Thread(target=mainWindow, args=(q,)).start()
## Ende Start Fenster
die fehlermeldung beim Programmstart:
Traceback (most recent call last):
File "C:/socketserver_01g_QueueQueue.py", line 34, in <module>
serverThread = Thread(target=server.serve_forever, myQueue=(q))
TypeError: __init__() got an unexpected keyword argument 'myQueue'
Process finished with exit code 1
Vielen Dank
Re: einer abgeleiteten Klasse in einem Thread eine Queue mitgeben
Verfasst: Donnerstag 2. März 2017, 20:03
von BlackJack
@XCDRiVER: Erst mal: Die GUI würde ich nicht in einem eigenen Thread starten. Die würde ich immer im Hauptthread lassen. Beim gezeigten Programm macht es ja auch gar keinen Sinn am Ende *drei* Threads zu haben und Du würdest nach dem Start dann ja sowieso gleich wieder ein `join()` machen. Dem `MyUdpHandler` (schlechter Name) kannst Du nichts in der `__init__()` mitgeben. Die Exemplare erstellst Du doch auch gar nicht, sondern der Server. Der gibt dem Handler aber sich selbst mit und in der `handle`-Methode ist das Server-Objekt auch verfügbar über `self.server`. Das heisst Du kannst im Server die `__init__()` implementieren und dort zusätzliche Argumente übergeben und Sachen an das Objekt binden.
Re: einer abgeleiteten Klasse in einem Thread eine Queue mitgeben
Verfasst: Donnerstag 2. März 2017, 20:25
von XCDRiVER
Hallo BlackJack,
vielen Dank für die Informationen.
wenn du von der Server-init schreibst der ich was mitgeben kann, meinst du direkt die init vom 'UDPServer()' in der socketserver.py?
Dort ist der richtige Platz um meine Queue 'anzumelden'?
Re: einer abgeleiteten Klasse in einem Thread eine Queue mitgeben
Verfasst: Donnerstag 2. März 2017, 21:00
von XCDRiVER
der betreffende Konstruktor für den Server wäre dann der TCPServer Konstruktor aus der socketserver.py
UDPServer selbst hat keinen Konstruktor, nur ein paar Funktionen und leitet vom TCPServer ab.
kann ich diesen TCPServer Konstruktor aus meinem Programm heraus erweitern?
Ich würde wirklich sehr ungerne in den Bibliotheken herum schreiben.
PS: Ja es geht wohl, ich denke ich habe es
Re: einer abgeleiteten Klasse in einem Thread eine Queue mitgeben
Verfasst: Donnerstag 2. März 2017, 21:17
von Sirius3
@XCDRiVER: Klassen erweitert man, indem man sie vererbt, genauso wie UDPServer die Funktionalität von TCPServer erbt, so mußt Du halt eine eigene Klasse mit einer __init__ schreiben, die von UDPServer erbt. Deine mainWindow-Klasse ist übrigens seltsam. Eine __init__-Methode sollte nicht endlos laufen.
Re: einer abgeleiteten Klasse in einem Thread eine Queue mitgeben
Verfasst: Donnerstag 2. März 2017, 21:26
von XCDRiVER
@Sirius3,
vielen dank, das mit der GUI hat BlackJack auch gesagt, da kümmere ich mich auch drum.
ich denke die Queue habe ich jetzt am laufen, ich habe mir, wie ihr beschrieben habt, eine eigene UDPServer-Klasse abgeleitet.
Ich bastele mal noch ein wenig und melde mich bei Problemen wieder,
übrigens:
das ist eine Spitzen-Reaktionszeit hier im Python-Forum.
und dazu beeindruckend kompetent. Vielen Dank
Re: einer abgeleiteten Klasse in einem Thread eine Queue mitgeben
Verfasst: Freitag 17. März 2017, 18:39
von XCDRiVER
Hallo Forum,
ich habe hier im Code folgendes Problem,
die Informationen, die als 'self.data' in der Klasse MyUdpHandler anstehen, müssten (irgendwie artgerecht) zur Klasse myUDPServer transportiert werden, damit ich die mit der Queue q an meine GUI weiterreichen kann.
So denke ich mir das zumindest.
Ich bräuchte mal einen Schubs wie ich da am besten weiter vorgehen sollte.
(Zeile 9 ist nur zum Test da ob die Queue auch funktioniert)
Vielen Dank.
Code: Alles auswählen
from queue import Queue, Empty
from tkinter import Tk, Frame, Label
class myUDPServer(UDPServer):
def __init__(self, server_address, RequestHandlerClass, q, bind_and_activate=True):
UDPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate=True)
self.q = q
self.daten = self.server_address
self.q.put(self.daten)
class MyUdpHandler(BaseRequestHandler):
def handle(self):
self.data = self.request[0].strip()
## socket = self.request[1]
print("[{}] - {} - {}".format(self.client_address[0], self.client_address[1], self.data.decode()))
class mainWindow(Frame):
def __init__(self, q, master=None):
super(mainWindow, self).__init__(master)
self.pack()
self.q = q
self.message = self.q.get(timeout=1)
self.labelData = Label(self, text=self.message)
self.labelData.pack()
if __name__ == "__main__":
q = Queue()
## Serverstart als eigener Thread ------------------------------------
HOST, PORT = "", 51456
server = myUDPServer((HOST, PORT), MyUdpHandler, q)
serverThread = Thread(target=server.serve_forever)
serverThread.start()
## Ende Serverstart
## Starte Fenster ----------------------------------------------------
root = Tk()
fenster = mainWindow(q, master=root)
fenster.mainloop()
## Ende Start Fenster
Re: einer abgeleiteten Klasse in einem Thread eine Queue mitgeben
Verfasst: Freitag 17. März 2017, 18:54
von BlackJack
@XCDRiVER: Der Handler kennt ja den Server, der hat den als Attribut, also kannst Du darüber auch problemlos auf dessen `q`-Attribut zugreifen.
Re: einer abgeleiteten Klasse in einem Thread eine Queue mitgeben
Verfasst: Freitag 17. März 2017, 19:18
von XCDRiVER
@BlackJack, ich hab ein paar Zeilen Code ausprobiert aber
ich hab keinen Schimmer wo ich was machen muss, um an die Daten vom handle() zu kommen.
self.q in den handle() zu schreiben funktioniert leider nicht. Dort ist der nicht bekannt.
Ich stehe auf dem Schlauch ...
Re: einer abgeleiteten Klasse in einem Thread eine Queue mitgeben
Verfasst: Freitag 17. März 2017, 19:34
von __deets__
Na dann lies mal
https://docs.python.org/2/library/socke ... er-objects aufmerksam durch, insbesondere die Beschreibung der Methode "handle()".
Kleiner Tipp: faengt an mit "and the server instance as ..."
Re: einer abgeleiteten Klasse in einem Thread eine Queue mitgeben
Verfasst: Freitag 17. März 2017, 20:57
von XCDRiVER
@__deets__ habe ich self.server so korrekt eingesetzt? Zumindest bekomme ich tatsächlich Daten aus der handle()
Vielen Dank bis hier her, ich probiere mal noch etwas und melde mich dann wieder. Dankeschöööön
Code: Alles auswählen
#socketserverUDP von docs.python.org
from socketserver import BaseRequestHandler, UDPServer
from threading import Thread
from queue import Queue, Empty
from tkinter import Tk, Frame, Label
class myUDPServer(UDPServer):
def __init__(self, server_address, RequestHandlerClass, q, bind_and_activate=True):
UDPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate=True)
self.q = q
class MyUdpHandler(BaseRequestHandler):
def handle(self):
self.data = self.request[0].strip()
## socket = self.request[1]
self.server.q.put(self.data)
print("[{}] - {} - {}".format(self.client_address[0], self.client_address[1], self.data.decode()))
class mainWindow(Frame):
def __init__(self, q, master=None):
super(mainWindow, self).__init__(master)
self.pack()
self.q = q
self.message = self.q.get(timeout=1)
self.labelData = Label(self, text=self.message)
self.labelData.pack()
if __name__ == "__main__":
q = Queue()
## Serverstart als eigener Thread ------------------------------------
HOST, PORT = "", 51456
server = myUDPServer((HOST, PORT), MyUdpHandler, q)
serverThread = Thread(target=server.serve_forever)
serverThread.start()
## Ende Serverstart
## Starte Fenster ----------------------------------------------------
root = Tk()
fenster = mainWindow(q, master=root)
fenster.mainloop()
## Ende Start Fenster
Re: einer abgeleiteten Klasse in einem Thread eine Queue mitgeben
Verfasst: Samstag 18. März 2017, 13:58
von __deets__
Grundsaetzlich ja, wie sinnvoll die gesamte Vorgehensweise ist, steht auf einem anderen Blatt. Ich wuerde ja in einem Timer periodisch pruefen, statt hart eine Sekunde zu warten. Wenn du das tust, brauchst du die ganze Nebenlaeufigkeit nicht & kannst deine Anfrage gleich synchron machen.