Seite 1 von 1

Hilfe bei dynamischem Eventhandling!

Verfasst: Samstag 17. Mai 2008, 15:27
von Manuela
Hallo!

Ich möchte über 2 Buttons einem Panel jeweils einen Text, ein Textcontrol und Spinbuttons dynamisch hinzufügen oder entfernen.
Die jeweiligen Spinbuttons verändern dann den entsprechenden Statictext und den Zahlenwert im zugehörigen Textcontrol (ähnlich einem Spincontrol).

Wie kann ich die Widgets, welche sich nach obigem Bsp. in dem Tupel dirfields befinden, so ansprechen, dass die Spinbuttons nur die zugehörigen Textcontols verändern?

Bei meiner Fassung verändern alle Spinbuttons die Werte aller Textcontrols und nicht nur die des jeweils zugehörigen.


Code: Alles auswählen


self.dirfields = [] 
self.values = []

...

     def DIALOG_HINZU(self,evt):

        self.Freeze() 

        fields = self.dirfields
        values=self.values
        self.flex = self.page2.ID_FLEX
        basecount = len(fields) + 1
        
        
        # Label
        label = "Text %i:" % (self.count + basecount) 
        new_label = wx.StaticText( self.page2, label = label)
        self.flex.Add( new_label, 0, wx.ALIGN_CENTER|wx.LEFT|wx.TOP|wx.BOTTOM, 5 )
    
        # Textctrl
        new_textctrl = wx.TextCtrl(self.page2, wx.ID_ANY,value = "3", size=[80,-1])
        self.flex.Add(new_textctrl, 0, wx.ALIGN_CENTER|wx.LEFT|wx.TOP|wx.BOTTOM, 5 )
       
        self.values.append(float(new_textctrl.GetValue()))
 
        #SpinButtons
        new_spinbuttons = wx.SpinButton(self.page2,wx.ID_ANY,size=[16,20],style = wx.SP_VERTICAL)
        new_spinbuttons.SetRange( 0, 10000000 )
        new_spinbuttons.SetValue( 0 )
        self.flex.Add(new_spinbuttons, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP|wx.BOTTOM, 5 )
       
        self.Bind(wx.EVT_SPIN_UP, self.values_erhoehen, new_spinbuttons)

        # Zur Feldliste
        fields.append((new_label, new_textctrl, new_spinbuttons))  
        self.page2.Layout()

        self.Thaw()
        
        
    def DIALOG_ENTFERNEN(self,evt):
     
        #self.count=self.count-1
        fields = self.dirfields
        values=self.values
        self.flex = self.page2.ID_FLEX
        
        # Überzählige Felder löschen
        if self.count < len(fields): 
            old_label, old_textctrl, old_spinbuttons = fields.pop()
            self.flex.Detach(old_textctrl)
            old_textctrl.Destroy()
            self.flex.Detach(old_label)
            old_label.Destroy()
            self.flex.Detach(old_spinbuttons)
            old_spinbuttons.Destroy()  
         
            del self.values[-1]

            
    
    def values_erhoehen(self,event):
       
        for (label, textctrl, spinbuttons) in (self.dirfields):
            
            self.values=float(textctrl.GetValue())
            self.values=self.values+0.1
            textctrl.SetValue(str(self.values))

    def values_verringern(self,event):
       
        for (label, textctrl, spinbuttons) in (self.dirfields):
            
            self.values=float(textctrl.GetValue())
            self.values=self.values-0.1
            textctrl.SetValue(str(self.values))

Verfasst: Samstag 17. Mai 2008, 19:04
von martin101986
Hallo Manuela,

der Fehler liegt in den beiden Methoden values_erhoehen und values_verringern.

Code: Alles auswählen

for (label, textctrl, spinbuttons) in (self.dirfields):
           
            self.values=float(textctrl.GetValue())
            self.values=self.values+0.1
            textctrl.SetValue(str(self.values))
In dieser for-Schleife erhälst für jede TextCtrl in self.dirfields ein Objekt. Daher wird jede TextCtrl um 0,1 erhöht.

Lösungsvorschlag:

Du könntest wenn neue Elemente hinzugefügt werden den SpinButtons eine fixe ID vergeben. Diese ID sollte der Position in der Liste self.dirfields entsprechen(z.B. SpinButton 1 = ID 1, an erster Position in der Liste, SpinButton 2 = ID 2 zweite Position in der Liste)

In den Methoden zur Eventbehandlung könntest du dann die ID des auslösenden SpinnButtons mit event.GetId abfragen und dann die entsprechende TextCtrl dann in der Liste ansprechen.

Code: Alles auswählen

textctrlpos = event.GetId()
self.dirfields[textctrlpos][2].SetValue(str(self.values))
Sollte so funktionen und hoffe ich habe dir weitergeholfen.

Grüße Martin

Verfasst: Sonntag 18. Mai 2008, 19:33
von Manuela
Danke Martin, das war der Fehler.

Ich habe nun jedem SpinButton eine aufsteigende ID zugewiesen.

Dennoch stellt sich mir die Frage, ob es auch ohne diese Zuweisung funktionieren könnte. Da ich in meinem Panel mehrere solcher dynamischen Dialoge benötige, wird es mit der Zeit wohl etwas verwirrend.
Generell sind die Textcontrols und Spinbuttons ja alle schön geordnet in dem Tupel dirfields, ich müsste diese nur irgendwie ansprechen.

Verfasst: Montag 19. Mai 2008, 16:43
von martin101986
Hallo Manuela,

was genau meinst du wird mit der Zeit verwirrend? Welchen Zweck erfüllen eigentlich diese SpinButton in Kombination mit der TextCtrl?

Grüße Martin

Verfasst: Mittwoch 28. Mai 2008, 22:49
von Manuela
Ich hatte mit nur ein eigenes kleines Fließkomma-Spincontrol gebastelt.