I have created a class for an animated tk frame that can be moved across the screen. For example, the user might click a button and the frame would then slide into view, rather than simply appear at a fixed location. The effect works perfectly, but there is a problem that I will outline below. First, here is the code for the class, which I have saved as a module to be imported into the main application:
import tkinter as tk
import customtkinter as ctk
class MyFrame(ctk.CTkFrame):
def __init__(self,master,height,width,placerow,startcol,endcol):
super().__init__(master)
# initialize instance variables
self.master = master
self.height = height
self.width = width
self.placerow = placerow
self.startcol = startcol
self.endcol = endcol
# set parameters based on instance variables
self.configure(width= width)
self.configure(height= height)
def MoveFrameRight(self):
global colInt
colInt = self.startcol
self.ShiftFrameRight()
def ShiftFrameRight(self):
global colInt
if colInt < self.endcol:
colInt = colInt 1
self.place(x=colInt,y=self.placerow)
self.master.after(1,self.ShiftFrameRight)
And here is how the class would be implemented in the main application:
import ModCtkFrameAnimated
FrameName=ModCtkFrameAnimated.MyFrame(RootWindow,300,100,10,10,300)
FrameName.MoveFrameRight()
print("Done")
I included the print("Done") statement to illustrate the problem. When FrameName.MoveFrameRight() is called, the function works fine, but it does not wait until completion before moving to the print("Done") line. So in real world code, it's un-usable. I have had some experience with the wait_window() function. But in this case, I don't want to destroy the frame, so that will not work here. I simply want to have the MoveFrameRight() function complete fully before moving to the next line of code in the main application. Any suggestions appreciated.
CodePudding user response:
You can wait on tkinter variables to change with the wait_variable
method. Do this by creating a variable, setting it to a value, resetting the value when your animation is finished, set the code in motion, then wait for the variable to be set. While tkinter is waiting it's able to process events as normal.
class MyFrame(ctk.CTkFrame):
def __init__(self,master,height,width,placerow,startcol,endcol):
...
self.flag = tk.IntVar(value=0)
...
def MoveFrameRight(self):
...
self.flag.set(1)
...
self.ShiftFrameRight()
self.wait_variable(self.flag)
def ShiftFrameRight(self):
global colInt
if colInt < self.endcol:
...
else:
self.flag.set(0)