Frage zu SpinCtrl

Plattformunabhängige GUIs mit wxWidgets.
Antworten
schwedenmann
User
Beiträge: 42
Registriert: Sonntag 21. Oktober 2007, 13:38
Wohnort: Wegberg

Hallo

Habe folgendes Demoprogramm modifiziert
[url][http://wiki.wxpython.org/AnotherTutoria ... inCtrl/url] spinctrl.py

hier meine Modifikation

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
# spinctrl.py
 
import wx
class MyDialog(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(350, 310))
        wx.StaticText(self, -1, 'Zinseszins - Endkapitalberechnung ', (20,20))
        wx.StaticText(self, -1, 'Anfangskapital: ', (20, 80))
        wx.StaticText(self, -1, 'Laufzeit: ',  (20, 100))
        wx.StaticText(self, -1, 'Zinssatz: ',  (20, 125))
        wx.StaticText(self, -1, 'Zinszahlungen: ',  (20, 150))
        wx.StaticText(self, -1, 'Endkapital: ', (20, 225))
        
        self.SetBackgroundColour('Orange')
        self.endkapital =  wx.StaticText(self, -1, '', (225, 225))
        self.sk = wx.SpinCtrl(self, -1, '',  (150, 75), (60, -1))
        self.sk.SetRange(-459, 1000)
        self.sk.SetValue(0)
        self.lz = wx.SpinCtrl(self, -1, '', (150, 100), (60, -1))
        self.lz.SetRange(0, 50)
        self.lz.SetValue(0)
        self.zs = wx.SpinCtrl(self, -1, '', (150, 125), (60, -1))
        self.zs.SetRange(0, 20)
        self.zs.SetValue(0)
        self.zz = wx.SpinCtrl(self, -1, '', (150, 150), (60, -1))
        self.zz.SetRange(0, 20)
        self.zz.SetValue(0)
 
        compute_btn = wx.Button(self, 1, 'Berechnen', (70, 250))
        compute_btn.SetFocus()
        clear_btn = wx.Button(self, 2, 'Beenden', (185, 250))
 
        self.Bind(wx.EVT_BUTTON, self.OnCompute, id=1)
        self.Bind(wx.EVT_BUTTON, self.OnClose, id=2)
        self.Bind(wx.EVT_CLOSE, self.OnClose)
 
    def OnCompute(self, event):
         startkapital = self.sk.GetValue()
         laufzeit = self.lz.GetValue()
         zinssatz = self.zs.GetValue()
         zinszahlungen = self.zz.GetValue()
         cels = startkapital * (1 + zinssatz/(100*zinszahlungen))**(laufzeit*zinszahlungen)
         self.endkapital.SetLabel(str(cels))
 
    def OnClose(self, event):
         self.Destroy()
 
class MyApp(wx.App):
     def OnInit(self):
         dlg = MyDialog(None, -1, 'Zinseszins.py')
         dlg.Show(True)
         dlg.Centre()
         return True
 
app = MyApp(0)
app.MainLoop()
Das Programm gibt mir immer nur den Wert der Eingabe von startkapital (sk) zurück, wo liegt der Fehler
mfg
schwedenmann
BlackJack

@schwedenmann: Rechnen mit ganzen Zahlen:

Code: Alles auswählen

In [86]: 100 * (1 + 7 / (100 * 42))**(23 * 42)
Out[86]: 100

In [87]: (1 + 7 / (100 * 42))**(23 * 42)
Out[87]: 1

In [88]: (1 + 7 / (100 * 42))
Out[88]: 1

In [89]: 7 / (100 * 42)
Out[89]: 0
Du musst halt dafür sorgen, dass die Berechnungen mit Gleitkommazahlen ausgeführt werden.

Sonstige Anmerkungen: Statisches, pixelgenaues Layout ist kaputtes Design. Das verwendet man heutzutage nicht mehr. `wx` bietet verschiedene Sizer um das GUI-Layout dynamisch zu gestalten und damit unabhängig von Anzeigegrösse, Display-Auflösung, Schriftarten- und Grössen, und so weiter, zu machen.

Statt -1 bei IDs sollte man `wx.ID_ANY` nehmen, damit dem Leser eher klar ist, was das Argument bedeutet.

Man darf nicht selber irgendwelche festen IDs verwenden! Es gibt IDs die von `wx` schon mit einer Bedeutung vorbelegt sind. Da können „interessante“ Sachen passieren wenn man einfach so welche nimmt, von denen man nicht weiss ob sie nicht schon eine Bedeutung haben. Garantiert unbenutzte kann man mit `wx.NewId()` erstellen. Das ist aber meistens gar nicht nötig. Man kann oft auch einfach `wx.ID_ANY` nehmen und dann bei anderen Methoden statt einer ID das Objekt selbst übergeben. Oder man verwendet eine vorgegebene ID falls man eine passende findet. Zum Beispiel `wx.ID_EXIT` für eine Schaltfläche, die das Programm beendet. Wenn man dort dann noch als Text eine leere Zeichenkette verwendet, werden Standard-Icon und Beschriftung für die Aktion verwendet:

Code: Alles auswählen

        compute_btn = wx.Button(self, wx.ID_APPLY, '', (70, 250))
        compute_btn.SetFocus()
        clear_btn = wx.Button(self, wx.ID_EXIT, '', (185, 250))
        
        self.Bind(wx.EVT_BUTTON, self.OnCompute, compute_btn)
        self.Bind(wx.EVT_BUTTON, self.OnClose, clear_btn)
Attributnamen wie `sk`, `lz`, `zs`, oder `zz` gehen ja mal gar nicht.

Man sollte Dialoge nicht selber platzieren. Das kann Anwender gehörig nerven wenn Fenster nicht da erscheinen wo freier Platz auf dem Desktop ist, sondern unbedingt in der Mitte aufgehen wollen. Wenn man das haben möchte, dann kann man das als Anwender der Fensterverwaltung mitteilen.

Die Grenzwerte für die Zahleneingabe solltest Du noch einmal überdenken. Die kann man auch so setzen, dass ein `ZeroDivisionError` vermieden wird.
schwedenmann
User
Beiträge: 42
Registriert: Sonntag 21. Oktober 2007, 13:38
Wohnort: Wegberg

Hallo

Danke.

Hab jetzt erstmal so geändert

Code: Alles auswählen

def OnCompute(self, event):
         startkapital = float(self.sk.GetValue())
         laufzeit = int(self.lz.GetValue())
         zinssatz = float(self.zs.GetValue())
         zinszahlungen = float(self.zz.GetValue())
         cels = round (startkapital * (1 + zinssatz/(100*zinszahlungen))**(laufzeit*zinszahlungen), 2)
         self.endkapital.SetLabel(str(cels))
Kann man das so stehen lassen, oder sollte man flot int andrs handhaben?

Zu den aboluten px-Angabne, das sind jetzt meine ersten Anfänge mit GUIprogrammierung, ist nur eine Übung, damit ich den GrundAufbau bei wxPython verstehen lerne.

Zu den Attributen lz, sk etc., sollen, müsen das komplette Wörter, ev. sogar groß geschrieben sein ?
mfg
schwedenmann
deets

Nein, nicht grossgeschrieben - lies dir mal PEP8 durch, das sind Hinweise, wie Python-Code formatiert sein sollte.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Das kommt darauf an, ich persönlich würde für lokale Variabeln der PEP-8 auf jeden Fall folgen, bei Funktionen/Methoden scheiden sich die Geister, laut PEP8 lautet deine Funktion "on_compute" und nach wxPython-Konvention so wie du sie genannt hast, "OnCompute".
the more they change the more they stay the same
Antworten