Das wäre genau das was ich brauche

Wie kann ich eine solche zeitgesteuerte Verschiebung erzeugen?
Hier ein Beispiel. Das Beispiel zeigt das Prinzip, ist aber kein Beispiel für schöne OOP:apple hat geschrieben:Wie kann ich eine solche zeitgesteuerte Verschiebung erzeugen?
Code: Alles auswählen
import tkinter as tk
move_element = None
move_yi = 0
move_yn = 0
move_step = -1
def do_move():
timestep=3
global move_element
global move_yi
global move_yn
global move_step
move_yi = move_yi + move_step
move_element.place(y=move_yi)
if move_yn != move_yi:
move_element.after(timestep,do_move)
def wish(element,y0,yn,step):
global move_element
move_element=element
global move_yi
move_yi=y0
global move_yn
move_yn=yn
global move_step
move_step=step
do_move()
class Application(tk.Tk):
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
self.geometry("280x370")
self.labelFrame = Labelframe(self,**{'width': 200, 'text': 'Screen', 'bd': 0, 'relief': 'flat', 'bg': '#d949d9', 'height': 300})
self.labelFrame.place(**{'y': '28', 'x': '43'})
class Labelframe(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.labelFrame = Labelframe_1(self,**{'width': 200, 'text': 'Noch ein Fenster', 'bd': 0, 'relief': 'flat', 'bg': '#d9d93c', 'height': 150})
self.labelFrame.place(**{'y': '300', 'x': '0'})
def wish_on(self):
wish(self.labelFrame,300,140,-1)
class Labelframe_1(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)
Application().mainloop()
Code: Alles auswählen
dir@client2087 /tmp $ python3.5 python-gui-messaging/GuiDesigner/main.py
Couldn't open file: guidesigner/Guidesigner.py
^CTraceback (most recent call last):
File "python-gui-messaging/GuiDesigner/main.py", line 2, in <module>
tk.Tk().mainloop('guidesigner/Guidesigner.py')
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 901, in mainloop
StatTkInter.Tk.mainloop(self)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.py", line 1131, in mainloop
self.tk.mainloop(n)
KeyboardInterrupt
dir@client2087 /tmp $ cd python-gui-messaging/GuiDesigner/
dir@client2087 /tmp/python-gui-messaging/GuiDesigner (master =) $ python3.5 main.py
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.py", line 1550, in __call__
return self.func(*args)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.py", line 596, in callit
func(*args)
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 2601, in DynLoad
exec(evcode)
File "guidesigner/Guidesigner.py", line 1, in <module>
Toplevel("DynTkInterGuiDesigner",title="DynTkInter GuiDesigner",geometry='+30+20',link="guidesigner/Modules.py")
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 926, in __init__
master = _initGuiContainer(kwargs,StatTkInter.Toplevel,self,myname,"toplevel",True,True,None,_TopLevelRoot._container)
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 827, in _initGuiContainer
GuiContainer.__init__(element,myname,select,mayhave_grid,isMainWindow,tkmaster,**kwargs)
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 604, in __init__
FileImportContainer(self) # if link != ""
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 788, in FileImportContainer
DynLoad(container.link)
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 2601, in DynLoad
exec(evcode)
File "guidesigner/Modules.py", line 57, in <module>
LabelFrame('BaseLayout',text="""Layout""",link="guidesigner/BaseLayout.py")
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 1102, in __init__
_initGuiContainer(kwargs,StatTkInter.LabelFrame,self,myname,"labelframe",True)
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 827, in _initGuiContainer
GuiContainer.__init__(element,myname,select,mayhave_grid,isMainWindow,tkmaster,**kwargs)
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 604, in __init__
FileImportContainer(self) # if link != ""
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 788, in FileImportContainer
DynLoad(container.link)
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 2601, in DynLoad
exec(evcode)
File "guidesigner/BaseLayout.py", line 7, in <module>
LabelFrame('GridLayout',link="guidesigner/GridLayout.py")
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 1102, in __init__
_initGuiContainer(kwargs,StatTkInter.LabelFrame,self,myname,"labelframe",True)
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 827, in _initGuiContainer
GuiContainer.__init__(element,myname,select,mayhave_grid,isMainWindow,tkmaster,**kwargs)
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 604, in __init__
FileImportContainer(self) # if link != ""
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 788, in FileImportContainer
DynLoad(container.link)
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 2599, in DynLoad
code = handle.read()
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 20599: ordinal not in range(128)
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.py", line 1550, in __call__
return self.func(*args)
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 933, in destroy
GuiElement.destroy(self)
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 298, in destroy
if widget_exists(self): self.tkClass.destroy(self)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.py", line 2146, in destroy
if self._name in self.master.children:
AttributeError: '_CreateTopLevelRoot' object has no attribute 'children'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "main.py", line 2, in <module>
tk.Tk().mainloop('guidesigner/Guidesigner.py')
File "/private/tmp/python-gui-messaging/GuiDesigner/DynTkInter.py", line 901, in mainloop
StatTkInter.Tk.mainloop(self)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.py", line 1131, in mainloop
self.tk.mainloop(n)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.py", line 1554, in __call__
self.widget._report_exception()
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.py", line 1297, in _report_exception
root.report_callback_exception(exc, val, tb)
AttributeError: '_CreateTopLevelRoot' object has no attribute 'report_callback_exception'
dir@client2087 /tmp/python-gui-messaging/GuiDesigner (master =) $0
Nein , ist nicht gewollt, bzw. ich war mir nicht bewusst, dass jemand nicht in das Verzeichnis selber gehen will. Danke, da kann man dann das noch in main.py einfügen:__deets__ hat geschrieben:Das man die main.py nicht aufrufen ausser man steht im Verzeichnis in dem sie liegt ist sicher gewollt?
Code: Alles auswählen
import os
os.chdir(os.path.dirname(os.path.realpath(__file__)))
Das brauchst Du mir nicht sagen, sondern dem Anfänger. Dieser sollte diese Globalen Variablen und die Funktion do_move und eventuell auch wish in einer Klasse kapseln. wish kann man aber auch als Funktion implementieren.Sirius3 hat geschrieben: @Alfons Mittelmeyer: global sollte in keinem Programm vorkommen. Zumal das meiste davon unnütz ist.
So eine wish Methode kann man für belebige GUI Elemente verwenden, sie soll daher keineswegs nur ein Bestandteil dieser Labelframe_1-Klasse seinSirius3 hat geschrieben:Wenn Du schon eine Labelframe_1-Klasse hast, dann könntest Du sie auch nutzen.
Sorry, dass ich meine Zeit nicht damit vertat, den Code für die GUI zu schreiben, sondern den Code generierte mit automatisch generierten Namen und Schlüsselwortargumenten.Sirius3 hat geschrieben:Du hast immer noch diese unmöglich komplizierte Variante, Schlüsselwortargumente zu übergeben, dass man es nicht lesen möchte. So nichtsagende Namen wie Labelframe_1 sollte man auch nicht benutzen.
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.Sirius3 hat geschrieben:Soetwas einem Anfänger zu zeigen, halte ich nicht für gut, das könnte jemand für brauchbar halten.
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()
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.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.
Also hier wird das Arbeitsverzeichnis schon wieder hergestellt, Dazu die Datei test.py in ein Unterverzeichnis subdir legen:BlackJack hat geschrieben:@Alfons Mittelmeyer: Python stellt gar nichts wieder her. Es wurde nichts ausserhalb des Prozesses verändert was wiederhergestellt werden müsste.
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())
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,__deets__ hat geschrieben:Ich bleibe bei meiner Einschaetzung, dass fuer eine moderne UI ein modernes UI-Framework notwendig ist.
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.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.
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()
Jedem wie es beliebt, wenn das Dich glücklicher macht:Sirius3 hat geschrieben:@Alfons Mittelmeyer: zum Wiederverwenden von Methoden hat man was ganz tolles erfunden: Objektorientierte Programmierung. Kannst Du Dir mal bei Gelegenheit anschauen.
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()