Über id auf Objektnamen o. sonstige Eigenschaften zugreifen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Caroline
User
Beiträge: 2
Registriert: Montag 2. März 2009, 12:12

Hallo,

ich habe folgendes Problem:
Ich habe eine Reihe von Buttons, die ich alle an die selbe Funktion binden möchte. In dieser Funktion will ich aber unterscheiden, von welchem Button das Event kam und dann einen bestimmten Eintrag in einem Dictionary ändern. Da das Dictionary intuitiv zu verstehen sein sollte, möchte ich mit aussagekräftigen Namen arbeiten und nicht nur mit Nummern (also nicht nur die id verwenden).
Beim Auslösen des Events kann ich, wie es auch in der Demo gemacht wird, die id des Buttons auslesen, nicht aber den Namen oder anderes, ich bekomme also nicht einfach eine Referenz auf den Button (wäre auch zu schön). Kann ich über die mir nun bekannte id irgendwas anderes über den Button rausfinden, z.B. den Namen, den ich ja in der Definiton vergeben kann?
Bisher fällt mir nur der Lösungsansatz ein, bei Erzeugen des Buttons einen Eintrag in ein weiteres (globales) Dictionary zu schreiben, das die id mit dem Namen verknüpft. Elegant finde ich das allerdings noch nicht.
Daher würde ich mich über Infos freuen. Suchmaschinen haben mich leider nicht weitergebracht.

Danke für's Lesen,
Carolin
BlackJack

Von welchem GUI-Toolkit reden wir denn überhaupt? Und mit ID ist hier etwas aus dem GUI-Toolkit gemeint, und nicht die ID des Python-Objekts, die man über die `id()`-Funktion bekommt!?

Üblicherweise sollte die Funktion ein Argument entgegen nehmen, welches entscheided was zu tun ist. Aus der Funktion kann man dann eine neue Funktion erstellen, bei der dieses Argument schon gebunden ist, bevor man die Funktion selber an die Schaltfläche bindet. Das geht mit einer ``lambda``-Funktion, einem "Closure", oder `functools.partial()`. Mehr oder weniger fiktive Beispiele:

Code: Alles auswählen

from GUI_Toolkit import Button

def func(name, event):
    print name
# 
# Mit ``lambda``:
# 
button_a = Button(name='Start', command=lambda n='Start', e: func(n, e))
button_b = Button(name='Stop', command=lambda n='Stop', e: func(n, e))
# 
# Mit `functools.partial()`:
# 
from functools import partial
button_a = Button(name='Start', command=partial(func, 'Start'))
button_b = Button(name='Stop', command=partial(func, 'Stop'))
# 
# Mit einem "Closure":
# 
def make_button(name):
    def call_func(event):
        func(name, event)
    return Button(name=name, command=call_func)

button_a = make_button('Start')
button_b = make_button('Stop')
Caroline
User
Beiträge: 2
Registriert: Montag 2. März 2009, 12:12

Sorry, hatte vergessen, das wir hier an der grapischen Oberflächee "kratzen". Ich arbeite mit wxPython.

Code: Alles auswählen

idDict={}
class PositionM1(wx.Panel):
    def __init__(self, parent, id, pos, size, _PosTab):
        
        wx.Panel.__init__(self, parent, id, pos, size)
        global idDict
        self.irasBut = wx.Button(self, 325, 'akt. ueb.', (165,60), name='iras')
        self.Bind(wx.EVT_BUTTON, self.irasButEvt, self.irasBut)

    def irasButEvt(self, evt):   
        global idDict     
        a=evt.GetId()
Ich meine schon, von der Python-Id des Button-Objekts zu reden (die ich hier mit 325 initialisiert habe). Diese kann ich wie im Codebeispiel in der Variablen a speichern. Was aber nicht funktioniert, wäre z.B. evt.GetName(), wobei der Button selbst aber die Funktionalität .GetName() besitzt und ich diese nach "self.irasBut = ..." auch aufrufen kann. Versuche ich evt.GetName(), so bekomme ich den Fehler: "AttributeError: 'CommandEvent' object has no attribute 'GetName'"

Meine Funktion irasButEvt kann ich leider nicht nach Belieben gestalten, da ich beim Aufruf davon abhängig bin, was das Event mir übergibt. Was genau dabei passiert, ist mir leider nicht klar, und ich wäre auch dankbar für Hinweise, wo ich allgemein etwas über Events nachlesen kann, wie ich z.B. rausfinde, welches Objekt welche Events erzeugen kann.

Muss gerade nochmal nachlesen, wie das mit den lambda-Funktionen war.
Aber es muss doch auch recht einfach möglich sein, über die id, die das Objekt eindeutig kennzeichnet, auf irgendwas anderes zuzugreifen! Oder ist die id am Ende eine Eigenschaft, die nur für Python selbst nutzbar ist?!

Grüße,
Carolin
BlackJack

@Caroline: Du meintest nicht die "Python-Id". In Python hat jedes Objekt eine ID, die solange das Objekt existiert eindeutig für dieses Objekt ist. Die kann man auch nicht selbst vergeben. Die ID im Quelltext ist eine ID, die `wxWidgets` intern verwendet. Die sollten auch eindeutig sein, darum sollte man sie nicht so vergeben, also als feste Zahl, sondern von `wx` eine freie Nummer auswählen lassen. Mittlerweile kann man da fast überall einfach eine -1 übergeben und `wx` sucht sich dann selbst eine ID aus.

Ein `Event` ist eben kein `Button`, also funtkionieren da auch die Methoden von `Button`\s nicht. So ein Ereignis kann ja auch durch andere Eingabeelemente ausgelöst werden. Ich würde das nicht an dem `Button` festmachen, sondern wie gesagt selbst dafür sorgen, dass ein weiteres Argument beim Aufruf übergeben wird. Und auf keinen Fall würde ich ein globales Dictionary für so etwas verwenden.

Nachlesen kann man auf der wxPython-Webseite und wenn dort etwas unklar bleibt, kann man es noch in der Dokumentation von wxWidgets versuchen. Das ist die C++-Bibliothek auf der wxPython aufbaut.

Ein gutes Buch soll `wxPython in Action` sein.
Antworten