Hilfe bei dynamischem Eventhandling!

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Manuela
User
Beiträge: 3
Registriert: Samstag 17. Mai 2008, 15:04

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))
Benutzeravatar
martin101986
User
Beiträge: 85
Registriert: Montag 3. Dezember 2007, 19:15
Wohnort: Steiermark, Österreich

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
Manuela
User
Beiträge: 3
Registriert: Samstag 17. Mai 2008, 15:04

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.
Benutzeravatar
martin101986
User
Beiträge: 85
Registriert: Montag 3. Dezember 2007, 19:15
Wohnort: Steiermark, Österreich

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
Manuela
User
Beiträge: 3
Registriert: Samstag 17. Mai 2008, 15:04

Ich hatte mit nur ein eigenes kleines Fließkomma-Spincontrol gebastelt.
Antworten