Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Tk_ani_Stacked_Frame.py
- try:
- from Tkinter import Frame, N, S, E, W
- except ImportError:
- from tkinter import Frame, N, S, E, W
- class Animation(object):
- def __init__(self, w, ticks, config_function, duration=1, interval_time=None, easing_function=None, start_value=0, end_value=1, callback=None):
- self._w = w
- self._tick = 0
- self._total_ticks = float(ticks)
- if easing_function is None:
- self._easing_function = lambda x: x
- self._duration = duration
- if interval_time:
- self._interval_time = int(interval_time * 1000)
- else:
- self._interval_time = int(duration * 1000 / self._total_ticks)
- self._start_value = start_value
- self._end_value = end_value
- self._interval_value = end_value - start_value
- self._config_function = config_function
- self._callback = callback
- def start_animation(self, after=0):
- if after != 0:
- self.after(int(after*1000), self._animate)
- else:
- self._animate()
- def _animate(self):
- t = self._tick / self._total_ticks
- value = self._start_value + self._interval_value * self._easing_function(t)
- self._config_function(value)
- self._tick += 1
- if self._tick <= self._total_ticks:
- self._w.after(self._interval_time, self._animate)
- else:
- if self._callback is not None:
- self._w.after(self._interval_time, self._callback)
- class Stacked_Frame(Frame):
- def __init__(self, master, animate=False, **kw):
- Frame.__init__(self, master, **kw)
- self._list_of_widgets = []
- self._current_index = None
- self._current_widget = None
- self.animate_direction=N
- self._animate = animate
- self._is_animating = False
- def add_widget(self, widget):
- self._list_of_widgets.append(widget)
- if self._current_index is None:
- self._current_index = 0
- self._show_widget(widget)
- index = len(self._list_of_widgets) - 1
- return index
- def remove_widget(self, widget):
- self._list_of_widgets.remove(widget)
- def insert_widget(self, index, widget):
- self._list_of_widgets.insert(index, widget)
- if self._current_index is None:
- self._current_index = 0
- self._show_widget(widget)
- def count(self):
- return len(self._list_of_widgets)
- def current_index(self):
- return self._current_index
- def index_of(self, widget):
- return self._list_of_widgets.index(widget)
- def set_current_index(self, index):
- if self._is_animating:
- return
- if index == self._current_index: return
- widget = self._list_of_widgets[index]
- self._current_index = index
- self._show_widget(widget)
- def set_current_widget(self, widget):
- if self._is_animating:
- return
- index = self._list_of_widgets.index(widget)
- self._current_index = index
- self._show_widget(widget)
- def widget(self, index):
- return self._list_of_widgets[index]
- def next(self):
- if self._current_index == len(self._list_of_widgets) - 1:
- return
- if self._is_animating:
- return
- self._current_index += 1
- self.animate_direction=N
- widget = self._list_of_widgets[self._current_index]
- self._show_widget(widget)
- def previous(self):
- if not self._current_index:
- return
- if self._is_animating:
- return
- self._current_index -= 1
- self.animate_direction=S
- widget = self._list_of_widgets[self._current_index]
- self._show_widget(widget)
- def _show_widget(self, widget):
- if self._current_widget is None:
- self._current_widget = widget
- widget.place(x=0, y=0, relwidth=1, relheight=1)
- else:
- if self._animate:
- old_widget = self._current_widget
- widget.place(relwidth=1, relheight=1)
- if self.animate_direction == W:
- start_value = 0
- end_value = self.winfo_width()
- def config_function(position):
- widget.place(x=position, y=0, anchor=N+E)
- old_widget.place(x=position, y=0, anchor=N+W)
- elif self.animate_direction == E:
- start_value = self.winfo_width()
- end_value = 0
- def config_function(position):
- widget.place(x=position, y=0, anchor=N+W)
- old_widget.place(x=position, y=0, anchor=N+E)
- elif self.animate_direction == S:
- start_value = 0
- end_value = self.winfo_height()
- def config_function(position):
- widget.place(x=0, y=position, anchor=S+W)
- old_widget.place(x=0, y=position, anchor=N+W)
- elif self.animate_direction == N:
- start_value = self.winfo_height()
- end_value = 0
- def config_function(position):
- widget.place(x=0, y=position, anchor=N+W)
- old_widget.place(x=0, y=position, anchor=S+W)
- animation = Animation(
- self,
- ticks=20,
- interval_time=0.05,
- start_value=start_value,
- end_value=end_value,
- config_function=config_function,
- callback=lambda widget=widget: self._on_finish_animation(widget))
- animation.start_animation()
- self._is_animating = True
- else:
- self._current_widget.place_forget()
- self._current_widget = widget
- widget.place(x=0, y=0, relwidth=1, relheight=1)
- def _on_finish_animation(self, widget):
- self._current_widget.place_forget()
- self._current_widget = widget
- self._is_animating = False
- if __name__ == "__main__":
- try:
- from Tkinter import Tk, Button, Label
- except ImportError:
- from tkinter import Tk, Button, Label
- root = Tk()
- stack = Stacked_Frame(root, width=300, height=400, animate=True)
- stack.pack(padx=5)
- frame1 = Frame(stack, background="red")
- Label(frame1, text="this is frame1").pack(expand=True)
- frame2 = Frame(stack, background="white")
- Label(frame2, text="this is frame2").pack(expand=True)
- frame3 = Frame(stack, background="yellow")
- Label(frame3, text="this is frame3").pack(expand=True)
- frame4 = Frame(stack, background="green")
- Label(frame4, text="this is frame4").pack(expand=True)
- stack.add_widget(frame1)
- stack.add_widget(frame2)
- stack.add_widget(frame3)
- stack.add_widget(frame4)
- row = Frame(root)
- row.pack(fill="x", pady=10, padx=5)
- Button(row, text="previous", command= lambda: stack.previous()).pack(side="left")
- Button(row, text="next", command= lambda: stack.next()).pack(side="left", padx=(8,0))
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement