Seite 2 von 3
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 12:59
von Sirius3
@Alfons Mittelmeyer: Du hast Den Code geschrieben, und deswegen sage ich es Dir. Wie soll jemand, der noch am Anfang steht, wissen wie es besser geht. Dass Dein GUI-Designer schrecklichen Code schreibt, hatten wir schon an anderer Stelle. Wenn man Code generiert, den man danach ändert, sollte der so lesbar sein, wie es eben geht, da es ja kein Problem für einen Code-Generierer ist, auch schöne Keyword-Argumente zu schreiben. Ansonsten ist der Code ja so simple, dass man dafür keinen Designer braucht.
Der selbe Code, nur ohne global, aber immer noch mit zu vielen festen Fenstergrößen und Positionen.
Code: Alles auswählen
import tkinter as tk
class Mainframe(tk.LabelFrame):
def __init__(self,master,**kwargs):
tk.LabelFrame.__init__(self,master,**kwargs)
tk.Button(self, text='wish on', command=self.wish_on).place(y=243,x=50)
self.button_frame = ButtonFrame(self, width=200, text='Noch ein Fenster', bd=0, relief='flat', bg='#d9d93c', height=150)
self.button_frame.place(y=300, x=0)
def wish_on(self):
self.button_frame.wish(300,140,-1)
class ButtonFrame(tk.LabelFrame):
def __init__(self, master, **kwargs):
tk.LabelFrame.__init__(self, master, **kwargs)
tk.Button(self, text='wish off', command=self.wish_off).place(y=83,x=50)
def wish_off(self):
self.wish(140,300,1)
def wish(self, y0, yn, step):
def do_move(y):
y += step
self.place(y=y)
if y != yn:
self.after(3, do_move, y)
do_move(y0)
def main():
app = tk.Tk()
app.geometry("280x370")
mainframe = Mainframe(app, width=200, text='Screen', bd=0, relief='flat', bg='#d949d9', height=300)
mainframe.place(y=28, x=43)
app.mainloop()
if __name__ == '__main__':
main()
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 12:59
von __deets__
Alfons Mittelmeyer hat geschrieben:Ich denke, es ist gut, dem Anfänger das Prinzip zu zeigen, wie etwas funktioniert. Und unschön anzusehender Code ist da gar nicht einmal so schlecht, da der Anfänger es dann schöner machen will und selber machen will, anstatt einfach nur die Vorlage zu kopieren.
Genau. Weil der Anfaenger, der bis dato keine Ahnung davon hat, wie man etwas macht, urploetzlich nicht nur aufhoert Code zu kopieren (was er bis jetzt immer getan hat), sondern auch noch einen Sinn fuer Code-Aesthetik entwickelt - unabhaengig von Dingen, die man ihm zeigt.
"Do as I say, not as I do" hat noch in keinem Kontext funktioniert. Gerade an den vielen Projekten und Codeschnipseln rund um den Pi sieht man, dass es keine Grenze nach unten gibt... aber fuer mich ist hier EOD. Ich bleibe bei meiner Einschaetzung, dass fuer eine moderne UI ein modernes UI-Framework notwendig ist.
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 14:22
von Alfons Mittelmeyer
BlackJack hat geschrieben:@Alfons Mittelmeyer: Python stellt gar nichts wieder her. Es wurde nichts ausserhalb des Prozesses verändert was wiederhergestellt werden müsste.
Also hier wird das Arbeitsverzeichnis schon wieder hergestellt, Dazu die Datei test.py in ein Unterverzeichnis subdir legen:
Code: Alles auswählen
import os
print("Workdir original:"+os.getcwd())
os.chdir(os.path.dirname(os.path.realpath(__file__)))
print("Workdir changed :"+os.getcwd())
Dann dieses Programm zweimal hintereinander aufrufen:
python3 subdir/test.py
python3 subdir/test.py
Beim zweiten Mal läßt sich das auch aufrufen, und wenn man es zum zweiten Mal aufruft, werden dieselben Verzeichnisse angezeigt, wie beim ersten Aufruf. Nichts wurde also verstellt, bzw es wurde nach Beendigung des ersten Aufrufes wieder zurückgesetzt.
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 14:36
von Sirius3
@Alfons Mittelmeyer: jeder Prozess hat sein eigenes Arbeitsverzeichnis. So dass wenn ein Prozess sein Verzeichnis verändert, hat das keine Auswirkung auf andere Prozesse. Du startest nacheinander zwei Prozesse, jedes startet mit dem ursprünglichen Pfad des aufrufenden Prozesses. Da wird wirklich nichts zurückgesetzt.
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 14:38
von Alfons Mittelmeyer
__deets__ hat geschrieben:Ich bleibe bei meiner Einschaetzung, dass fuer eine moderne UI ein modernes UI-Framework notwendig ist.
Ja, beim Raspberry Pi, wahrscheinlich auch auf dem PC mit Linux, sind solche Animationen mit after sehr flüssig. Aber unter Windows ist dieses nicht der Fall - zumindest nicht mit meinem Windows7 Ultimate 32 Bit. Wenn man solche Animationen auch für Windows programmieren möchte, sollte man ein entsprechendes modernes UI-Framework verwenden,
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 14:56
von Alfons Mittelmeyer
Sirius3 hat geschrieben:@Alfons Mittelmeyer: jeder Prozess hat sein eigenes Arbeitsverzeichnis. So dass wenn ein Prozess sein Verzeichnis verändert, hat das keine Auswirkung auf andere Prozesse. Du startest nacheinander zwei Prozesse, jedes startet mit dem ursprünglichen Pfad des aufrufenden Prozesses. Da wird wirklich nichts zurückgesetzt.
Naja, jedenfalls sorgt python dafür, dass der aktuelle Pfad der Shell unverändert bleibt - ob durch Zurücksetzen oder durch Verwendung eines Prozesses ist an sich schnuppe.
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 15:29
von Sirius3
@Alfons Mittelmeyer: Python sorgt für gar nichts. Man kann nur sein eigenes Arbeitsverzeichnis ändern, nicht das eines anderen Prozesses, das geht gar nicht. Und dass ein Modul von sich aus den Pfad ändert ist einfach nur unerwartet, damit rechnet niemand und stell Dir zwei Module vor, die das machen, dann kann man die nicht zusammen benutzen. Daher ist es höchst unangebracht, das zu tun.
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 16:16
von Alfons Mittelmeyer
@Sirius3: Wichtig ist eine flexible Programmierung, das heißt, man soll allgemein verwendbare Funktionen auch allgemein verwenden können. Die wish-Funktion als Methode für ein einziges GUI Element zu definieren, sollte nicht sein.
Ein Anwendung kann wachsen und am Ende viele unterschiedliche Fenster haben, die mit wish verschoben werden. Daher ist die wish Funktion gesondert zu implementieren. Hier einmal nicht mit globalen Variablen:
Code: Alles auswählen
import tkinter as tk
# ---- Definition of wish function ---------------
def wish(element,y0, yn, step,timestep):
def do_move(y):
y += step
element.place(y=y)
if y != yn:
element.after(timestep, do_move, y)
do_move(y0)
# ---- GUI ---------------------------------------
class Mainframe(tk.LabelFrame):
def __init__(self,master,**kwargs):
tk.LabelFrame.__init__(self,master,**kwargs)
tk.Button(self, text='wish on', command=self.wish_on).place(y=243,x=50)
self.button_frame = ButtonFrame(self, width=200, text='Noch ein Fenster', bd=0, relief='flat', bg='#d9d93c', height=150)
self.button_frame.place(y=300, x=0)
def wish_on(self):
wish(self.button_frame,300,140,-1,3)
class ButtonFrame(tk.LabelFrame):
def __init__(self, master, **kwargs):
tk.LabelFrame.__init__(self, master, **kwargs)
tk.Button(self, text='wish off', command=self.wish_off).place(y=83,x=50)
def wish_off(self):
wish(self,140,300,1,3)
def main():
app = tk.Tk()
app.geometry("280x370")
mainframe = Mainframe(app, width=200, text='Screen', bd=0, relief='flat', bg='#d949d9', height=300)
mainframe.place(y=28, x=43)
app.mainloop()
if __name__ == '__main__':
main()
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 16:25
von Sirius3
@Alfons Mittelmeyer: zum Wiederverwenden von Methoden hat man was ganz tolles erfunden: Objektorientierte Programmierung. Kannst Du Dir mal bei Gelegenheit anschauen.
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 17:02
von Alfons Mittelmeyer
Sirius3 hat geschrieben:@Alfons Mittelmeyer: zum Wiederverwenden von Methoden hat man was ganz tolles erfunden: Objektorientierte Programmierung. Kannst Du Dir mal bei Gelegenheit anschauen.
Jedem wie es beliebt, wenn das Dich glücklicher macht:
Code: Alles auswählen
import tkinter as tk
# ---- Definition of wish class ---------------
class WishClass():
def wish(self,element,y0, yn, step,timestep):
def do_move(y):
y += step
element.place(y=y)
if y != yn:
element.after(timestep, do_move, y)
do_move(y0)
# ---- GUI ---------------------------------------
class Mainframe(tk.LabelFrame):
def __init__(self,master,**kwargs):
tk.LabelFrame.__init__(self,master,**kwargs)
tk.Button(self, text='wish on', command=self.wish_on).place(y=243,x=50)
self.button_frame = ButtonFrame(self, width=200, text='Noch ein Fenster', bd=0, relief='flat', bg='#d9d93c', height=150)
self.button_frame.place(y=300, x=0)
self.wish_object=WishClass()
def wish_on(self):
self.wish_object.wish(self.button_frame,300,140,-1,3)
class ButtonFrame(tk.LabelFrame):
def __init__(self, master, **kwargs):
tk.LabelFrame.__init__(self, master, **kwargs)
tk.Button(self, text='wish off', command=self.wish_off).place(y=83,x=50)
self.wish_object=WishClass()
def wish_off(self):
self.wish_object.wish(self,140,300,1,3)
def main():
app = tk.Tk()
app.geometry("280x370")
mainframe = Mainframe(app, width=200, text='Screen', bd=0, relief='flat', bg='#d949d9', height=300)
mainframe.place(y=28, x=43)
app.mainloop()
if __name__ == '__main__':
main()
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 17:04
von kbr
Alfons Mittelmeyer hat geschrieben:Die wish-Funktion als Methode für ein einziges GUI Element zu definieren, sollte nicht sein.
Das ist ganz richtig erkannt und somit ist die Funktion ein heißer Kandidat als Methode einer Superklasse.
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 17:37
von BlackJack
@Alfons Mittelmeyer: Die `WishClass` ist semantisch keine Klasse. Zudem ist der Name ziemlich schlecht. Das `Class` hat da nichts zu suchen und mit Wünschen hat das auch alles nichts zu tun.

Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 17:54
von Sirius3
@Alfons Mittelmeyer: das macht mich nicht glücklich, weil Du ja jetzt nur die Funktion eine Ebene tiefer geschoben hast und class drumrum geschrieben. Wahrscheinlich braucht man die wish-Methode (eigentlich swipe) nur in Frames, so dass man am einfachsten eine SwipeFrame-Klasse von Frame ableitet und davon wieder konkrete Frames.
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 18:37
von Alfons Mittelmeyer
BlackJack hat geschrieben:@Alfons Mittelmeyer: Die `WishClass` ist semantisch keine Klasse.
Sementisch war das schon eine Klasse, weil sie mit class definiert war. Allerdings wie es codiert war, ist zum Haareausraufen. Die Funktion war von Sirius3.
@Siorius3: In einer anderen Programmiersprache würde man so etwas nie schreiben, und auch in Python sollte man solches nicht tun. Normalerweise sollte man davon ausgehen, dass nach Beendigung der Methode "wish" die Parameter nicht mehr vorhanden sein sollten und deshalb weitere Aufrufe mittels after von do_move die Werte eigentlich nicht mehr finden sollten. Wenn es in Python trotzdem geht, sollte kein Grund sein, so etwas zu codieren.
Eine richtige Implementierung ist die Verwendung von Objektattributen. Durch die Verwendung von Objektattributen ist es auch möglich, mehrere Fenster mehr oder minder gleichzeitig zu verschieben, da jedes Objekt dann die eigenen Werte hat. Die WishKlasse mehr oder minder richtig implementiert, wäre dann:
Code: Alles auswählen
class WishClass():
def wish(self,element,y0, yn, step,timestep):
self.element = element
self.yi = y0
self.yn = yn
self.step=step
self.timestep = timestep
self.do_move()
def do_move(self):
self.yi += self.step
self.element.place(y=self.yi)
if self.yi != self.yn:
self.element.after(self.timestep, self.do_move)
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 19:11
von Alfons Mittelmeyer
Sirius3 hat geschrieben:@Alfons Mittelmeyer: ...Wahrscheinlich braucht man die wish-Methode (eigentlich swipe) nur in Frames, so dass man am einfachsten eine SwipeFrame-Klasse von Frame ableitet und davon wieder konkrete Frames.
Richtig, das wäre auch mein Vorschlag:
Code: Alles auswählen
import tkinter as tk
# ---- Definition of SwipeFrame ---------------
class SwipeFrame(tk.Frame):
def __init__(self,master, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
def wish(self,y0, yn, step,timestep):
self.yi = y0
self.yn = yn
self.step=step
self.timestep = timestep
self.do_move()
def do_move(self):
self.yi += self.step
self.place(y=self.yi)
if self.yi != self.yn:
self.after(self.timestep, self.do_move)
# ---- GUI ---------------------------------------
class Mainframe(tk.LabelFrame):
def __init__(self,master,**kwargs):
tk.LabelFrame.__init__(self,master,**kwargs)
tk.Button(self, text='wish on', command=self.wish_on).place(y=243,x=50)
self.button_frame = ButtonFrame(self, width=200, bd=0, relief='flat', bg='#d9d93c', height=150)
self.button_frame.place(y=300, x=0)
def wish_on(self):
self.button_frame.wish(300,140,-1,3)
class ButtonFrame(SwipeFrame):
def __init__(self, master, **kwargs):
SwipeFrame.__init__(self, master, **kwargs)
tk.Label(self, text='Swipe Window').place(y=0,x=0)
tk.Button(self, text='wish off',command=self.wish_off).place(y=83,x=50)
def wish_off(self):
self.wish(140,300,1,3)
def main():
app = tk.Tk()
app.geometry("280x370")
mainframe = Mainframe(app, width=200, text='Screen', bd=0, relief='flat', bg='#d949d9', height=300)
mainframe.place(y=28, x=43)
app.mainloop()
if __name__ == '__main__':
main()
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 19:41
von Sirius3
@Alfons Mittelmeyer: das was Du da so verteufelst, weil Du es nicht kennst, nennt sich closure und existiert so in fast jeder modernen Programmiersprache. So lange eine Funktion schön kurz ist, hilft es, umständliches Kopieren von Argumenten in Attribute, die man eigentlich nicht in einer Funktion neu einführen sollte, zu verhindern.
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 20:17
von BlackJack
@Alfons Mittelmeyer: Das ist semantisch keine Klasse. Das ist nur formal Eine.
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 20:50
von Alfons Mittelmeyer
BlackJack hat geschrieben:@Alfons Mittelmeyer: Das ist semantisch keine Klasse. Das ist nur formal Eine.
Wieso ist das semantisch keine Klasse? Es ist natürlich eine Klasse. Nur macht so eine Klasse wenig Sinn, wenn man von dieser nur eine einzige Methode benützt. Dann kann man genauso gut eine Funktion nehmen.
Aber wenn man davon ausgeht, dass man das eh nur für einen SwipeFrame braucht, dann ist so ein SwipeFrame natürlich ein Klasse. Wenn man weiter davon ausgeht, dass diese Swipe Fenster alle gleich groß sind, dann kann man auch Größenangaben und Koordinatenangaben in diesen SwipeFrame verlagern.
Also SwipeFrame ist bestimmt eine Klasse:
Code: Alles auswählen
import tkinter as tk
# ---- Definition of SwipeFrame ---------------
class SwipeFrame(tk.Frame):
def __init__(self,master, **kwargs):
kwargs['width']=200
kwargs['height']=150
tk.Frame.__init__(self, master, **kwargs)
self.ydown=300
self.yup=150
self.timestep=3
self.place(y=self.ydown,x=0)
def wish_on(self):
self.wish(self.ydown,self.yup,-1,self.timestep)
def wish_off(self):
self.wish(self.yup,self.ydown,1,self.timestep)
def wish(self,y0, yn, step,timestep):
def do_move(y):
y += step
self.place(y=y)
if y != yn:
self.after(timestep, do_move,y)
do_move(y0)
# ---- GUI ---------------------------------------
class Mainframe(tk.Frame):
def __init__(self,master,**kwargs):
tk.Frame.__init__(self,master,**kwargs)
tk.Label(self, text='Screen',bg=self['bg']).place(y=0,x=0)
tk.Button(self, text='wish on', command=self.wish_on).place(y=243,x=50)
self.button_frame = ButtonFrame(self,bg='#d9d93c')
def wish_on(self):
self.button_frame.wish_on()
class ButtonFrame(SwipeFrame):
def __init__(self, master, **kwargs):
SwipeFrame.__init__(self, master, **kwargs)
tk.Label(self, text='Swipe Window',bg=self['bg']).place(y=0,x=0)
tk.Button(self, text='wish off',command=self.wish_off).place(y=93,x=50)
def main():
app = tk.Tk()
app.geometry("280x370")
mainframe = Mainframe(app, width=200, bg='#d949d9', height=300)
mainframe.place(y=28, x=43)
app.mainloop()
if __name__ == '__main__':
main()
asse:
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 21:27
von BlackJack
@Alfons Mittelmeyer: Es ist semantisch keine Klasse. Die Begründung hast Du ja selbst schon geschrieben.
Re: Wischfunktion durch Buttonklick hervorrufen
Verfasst: Mittwoch 19. April 2017, 21:53
von Alfons Mittelmeyer
BlackJack hat geschrieben:@Alfons Mittelmeyer: Es ist semantisch keine Klasse. Die Begründung hast Du ja selbst schon geschrieben.
Die Klasse ist syntaktisch richtig. Auch semantisch stimmt sie. Nur pragmatisch ist diese Klasse nicht sinnvoll.
Syntaktisch richtig wäre etwa dieses Datum: 29. Februar 2017
Semantisch ist dieses Datum allerdings falsch.
Pragmatisch unklug wäre es, stets nur am 29. Februar jährlich fällige Zahlungen zu leisten.