Seite 1 von 1
Problem mit wx.Timer
Verfasst: Montag 23. Juli 2012, 12:35
von red_dust
Hallo,
ich habe für mein Programm verschiedene Funktionen in eine Python Datei (keine Klasse) ausgelagert, einer der Funktionen ist:
Code: Alles auswählen
def getX(self, message='none'):
self.Log.info('Logmessage: '+message)
in einer weiteren Funktion starte ich einen Timer:
Code: Alles auswählen
self.timer = wx.Timer(self)
self.timer.Start(4000, oneShot=False)
self.Bind(wx.EVT_TIMER, getX(self, message='foo'))
die Funktion wird dann einmalig aufgerufen aber nicht alle 4 Sekunden, woran könnte das liegen?
Grüße
Re: Problem mit wx.Timer
Verfasst: Montag 23. Juli 2012, 13:02
von EyDu
Hallo,
ich kenne mich mit wx nicht besonders gut aus, aber auf jeden Fall ist die Zeile
falsch.
Der zweite Parameter muss eine Funktion oder irgend etwas anderes aufrufbares sein. Du übergibst aber das Ergebnis des Aufrufst ``getX(self, message='foo'))`` als Parameter an Bind. Das kanst du mittels lambda lösen. Etwas schöner wäre ``functools.partial``.
Sebastian
Re: Problem mit wx.Timer
Verfasst: Montag 23. Juli 2012, 13:03
von deets
Da faellt einem gleich so manches in's Auge. Statt "none" besser wirklich None nehmen, und darauf testen, und nur was ausgeben wenn "message is not None" ist. CamelCase in Methoden-Namen ist auch nicht PEP8-konform, und etwas in einem Timer zu machen das "get" am Anfang heisst klingt fuer mich komisch.
Doch das ist alles Kosmetik - zum eigentlichen Problem: du rufst deine Funktion ja einfach direkt auf, statt sie als callback zu uebergeben. Da du auch noch parametrisieren willst, kannst du das zb mit partial machen:
Code: Alles auswählen
from functools import partial
self.Bind(.., partial(self.getX, message='foo'))
Re: Problem mit wx.Timer
Verfasst: Montag 23. Juli 2012, 13:06
von BlackJack
@red_dust: Das liegt daran, dass *Du* die Funktion aufrufst und dann versuchst deren *Rückgabewert* an das Timer-Ereignis zu binden. Das zweite Argument bei Deinem `Bind()`-Aufruf ist also `None`, weil das der (implizite) Rückgabewert von Deiner `getX()`-Funktion ist. An der Stelle muss eine Funktion übergeben werden, die dann vom Timer aufgerufen werden kann. Ich nehme mal an Du suchst `functools.partial()` um eine solche Funktion aus dem `getX` und den Argumenten zu erstellen.
Ich bin mir auch fast sicher das `Bind()` ist so nicht vollständig, denn da kommt der erstellte Timer nirgends vor.
Edit: Verdammt, zu langsam.

Re: Problem mit wx.Timer
Verfasst: Montag 23. Juli 2012, 13:16
von red_dust
Danke schon mal für die Hilfe, das mit der Funktion habe ich jetzt verstanden
ich habe den Aufruf wie folgt korrigiert:
Code: Alles auswählen
self.timer = wx.Timer(self)
self.timer.Start(4000, oneShot=False)
self.Bind(wx.EVT_TIMER, partial(getX, message='test'), self.timer)
Jetzt bekomme ich allerdings den folgenden Fehler:
Code: Alles auswählen
AttributeError: 'TimerEvent' object has no attribute 'Log'
wenn ich übrigens ein self. vor die Funktion schreibe bekomme ich folgenden Fehler:
Code: Alles auswählen
AttributeError: 'MyProgram' object has no attribute 'getX'
woran liegt das?
Re: Problem mit wx.Timer
Verfasst: Montag 23. Juli 2012, 13:22
von lunar
Code: Alles auswählen
self.Bind(wx.EVT_TIMER, partial(self.getX, message='test'), self.timer)
Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 07:35
von red_dust
wenn ich denn Code so übernehme:
Code: Alles auswählen
self.Bind(wx.EVT_TIMER, partial(self.getX, message='test'), self.timer)
dann bekomme ich die Fehlermeldung:
Code: Alles auswählen
AttributeError: 'MyProgram' object has no attribute 'getX'
was ja eigetnlich klar ist, da self ja keine Instanz meines Funktionen-Containers ist, aber wie löse ich das Problem?
Ist mein Konzept schon von Grund auf falsch, die Funktionen in einer eigenen Datei auszulagern?
Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 07:42
von BlackJack
@red_dust: Dann ersetze ``self`` halt mit einer Referenz auf das passende Objekt. Aber was ist denn bitte ein „Funktionen-Container”? Und wenn `getX()` eine Funktion ist, warum heisst das erste Argument dann `self`? Das ist sehr verwirrend.
Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 10:13
von red_dust
Mit funktionen-Container meine ich:
ich habe für mein Programm verschiedene Funktionen in eine Python Datei (keine Klasse) ausgelagert
Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 10:21
von EyDu
Das nennt man "Modul"

Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 10:26
von red_dust
Ah okay, verstanden, sorry ich habs nicht so mit der Fachsprache.
Also mein Modul heißt HDDUpdate.py in diesem habe ich meine Funktionen gesammelt.
Hier
http://tutorial.pocoo.org/modules.html steht, dass ich einfach per Modulname.Funktion auf die Funktionen zugreifen kann, der Code:
Code: Alles auswählen
self.Bind(wx.EVT_TIMER, partial(HDDUpdate.getx, message='foo'), self.timer)
liefert aber auch eine Fehlermeldung:
Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 10:29
von lunar
@red_dust: Du musst das Modul natürlich auch importieren. Da es Dir aber offensichtlich an den entsprechenden Grundlagen fehlt, würde ich Dir für den Anfang raten, auf ein separates Modul zu verzichten, alle Funktionen in einer Datei zu belassen, und das Tutorial der Python-Dokumentation bis zum Schluss durchzuarbeiten.
Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 10:40
von red_dust
dass ich das Modul importieren muss ist mir klar, aber ich übergebe ja innerhalb des Moduls die Funktion getx an den Timer-Event Handler und nicht in meiner Hauptklasse.
Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 10:44
von lunar
@red_dust: Aha… ich glaube, jetzt kommt niemand mehr mit. Zeige uns bitte den
vollständigen Quelltext. Du kannst ihn beispielsweise auf
https://gist.github.com/ hochladen.
Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 12:32
von red_dust
Puhh das Programm ist schon ziemlich umfangreich,
im Prinzip habe ich meine Hauptklasse run.py
https://gist.github.com/3169445
in der ich per InitWidgetLists und OnInit (beide im Modul Widgets.py) meine Gui aufbaue und die Events zuweise.
in dem Modul OnEventsFunctions habe ich dann die Funktionen die aufgerufen werden wenn interagiert wird.
https://gist.github.com/3169436
darin wird dann das Modul HDDUpdate aufgerufen in dem meine tatsächlichen Funktionen hinterlegt sind
https://gist.github.com/3169428
Hoffe ihr könnt mir damit weiterhelfen
Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 14:47
von red_dust
ist es ratsam aus meinem Modul hddupdate eine eigene Klasse zu machen?
Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 15:19
von deets
es ist vor allem ratsam sich zu entscheiden, was HDDUpdate-Funktionen sein sollen - Funktionen? Dann gehoert dort kein self rein. Oder Methoden? Dann muessen sie in eine Klasse, und bei den Timer-callbacks muss dann ein Objekt davon existieren.
Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 15:49
von red_dust
okay wenn ich bei den Funktionen bleibe woran knüpfe ich dann das
?
Re: Problem mit wx.Timer
Verfasst: Dienstag 24. Juli 2012, 15:54
von deets
Na, wie rufst du die Funktion denn auf *ohne* Timer?