Im having trouble trying to time the update of a tkinter label image - python-3.x

I am trying to make a basic 4 frame animation, I cannot use a tkinter canvas as I want it to use the art which I have drawn (the files). There is nothing wrong with the file type as I have tested it on its own. However the code seems to just remove the window for the 6 seconds and then show the final frame.
import time
import tkinter
window=tkinter.Tk()
frame1=tkinter.PhotoImage(file="file1.ppm")
frame2=tkinter.PhotoImage(file="file2.ppm")
frame3=tkinter.PhotoImage(file="file3.ppm")
frame4=tkinter.PhotoImage(file="file4.ppm")
image=tkinter.Label(window,image=frame1)
image.pack()
time.sleep(2)
image.configure(image=frame2)
time.sleep(2)
image.configure(image=frame3)
time.sleep(2)
image.configure(image=frame4)
I'm not sure whether it is the "time.sleep" or the "image.configure" that is the problem but I have tried to mess around with different types of timing methods which also seem to fail.

import tkinter
window=tkinter.Tk()
frame1=tkinter.PhotoImage(file="file1.ppm")
frame2=tkinter.PhotoImage(file="file2.ppm")
frame3=tkinter.PhotoImage(file="file3.ppm")
frame4=tkinter.PhotoImage(file="file4.ppm")
image=tkinter.Label(window,image=frame1)
image.pack()
def loop(n):
frame = [frame1, frame2, frame3, frame4][n]
window.after(2000, lambda : image.configure(image=frame))
window.after(2000, lambda : loop((n+1)%4))
loop(1)

Related

Can you have two instances of tkinter in Python?

Is it possible to have two instances of tkinter ?
import tkinter as tk
import tkinter as sk
root = tk.Tk()
root2 = sk.Tk()
....some window with tk
....some window with sk
root.mainloop()
root2.mainloop()
then have a Toplevel() in both instances.
You can, but the way it works likely won't be like what you expect. Importing it twice isn't the problem (but neither is it the solution). No matter how you import it or how often you import it, creating more than one instance of Tk is the problem. Each instance is backed by a separate internal interpreter. Images and variables and widgets created in one won't exist in the other.
If you need more than one window, it's usually best if second and subsequent windows are instances of Toplevel.
By creating 2 instances or tkinter I can close one instance and all top Levels of that instance. Leaving the second Instance open and running with it's Toplevel instances. This is useful in the sense where I use it for a User preference file. Where it checks for a userfile database for keeping track of variables. I use a csv file to save user variable using pandas. This in turn keeps all the form information in my app safe from being erased after closing the application or accidentally closing the window. Adding AtExit saves the info closing the addinfo window and continues to run the main application. That was my reasoning for having asked the question. I have since found that using multiple Toplevel(s) is a better choice as it will also produce the same result. So my menu items all have a separate instance definition and can be closed in the same manner ,making error checks with each closed window.
from tkinter import Tk,Label,Entry,Button,Toplevel
root=Tk()
def about():
ab=Toplevel()
# About stuff for this window
ab.mainloop()
def info():
inf=Toplevel()
# Information Stuff for this window.
inf.mainloop()
def getUserInfo():
# User info using pandas
getUserInfo.mainloop()
root.mainloop()

Print Current Time In Tkinter

I have written some code in python for a live time in tkinter.
Whenever I run the code it comes up with some numbers on the tkinter window like 14342816time. Is there a way to fix this?
import tkinter
import datetime
window = tkinter.Tk()
def time():
datetime.datetime.now().time()
datetime.time(17, 3,)
print(datetime.datetime.now().time())
tkinter.Label(window, text = time).pack()
window.mainloop()
After some fixes to your code, I came up with the following, which should at least get you started toward what you want:
import datetime
import tkinter
def get_time():
return datetime.datetime.now().time()
root = tkinter.Tk()
tkinter.Label(root, text = get_time()).pack()
root.mainloop()
The imports are needed so that your program knows about the contents of the datetime and tkinter modules - you may be importing them already, however, I can't tell that for certain from what you posted. You need to create a window into which you put your label, which wasn't happening; following convention, I called that parent (and only) window "root". Then I put the Label into root. I changed the name of your time() function to get_time(), since it's best to avoid confusing fellow programmers (and maybe yourself) with a function that shares its name with another (the time() function in time). I removed two lines in get_time() that don't actually accomplish anything. Finally, I changed the print you had to a return, so that the value can be used by the code calling the function.
There are other improvements possible here. If you're content with the time as it is, you could eliminate the get_time function and just use datetime.datetime.now().time() instead of calling get_time(). However, I suspect you might want to do something to clean up that time before it is displayed, so I left it there. You might want to research the datetime and time modules some more, to see how to clean things up.

Defining TkInter StringVars in a loop

My program iterates through a list of values and creates a new frame with relevant information. I want to add a button to refresh the values in just one of the frames. The following image is a mockup of what I'm trying to achieve, where the "reload" button grabs new data for just one printer.
I'm running into an issue where only the last values get updated. The following code is an approximation of what I was trying:
import tkinter as tk
from tkinter import ttk
def buttonupdate(x):
return int(x.get())+1
root=tk.Tk()
values=[0,0,0,0,0,0,0]
stringVarList=[]
for i,item in enumerate(values):
newStringVar=tk.StringVar()
newStringVar.set(item)
stringVarList.append(newStringVar)
valueLabel=tk.Label(root, textvariable=stringVarList[i])
valueLabel.grid(row=0,column=i)
button=tk.Button(root, text="+1", command=lambda:stringVarList[i].set(buttonupdate(stringVarList[i])))
button.grid(row=1, column=i)
root.mainloop()
With this code, only the last value gets updated, no matter which button I press.
What can I try instead? Thank you.

How do I increase the speed of RawTurtle?

I'm currently using an embedded turtle canvas in a tkinter window. While it's intuitive that all I need to do is set my turtle to turtle.RawTurtle(canvas), there are some functions that just don't work, and I can't figure out why.
t.clear();t.pu();t.speed(0);t.ht();t.tracer(0)
But I get the error:
AttributeError: 'RawTurtle' object has no attribute 'tracer'
Despite this, many other functions work, such as clear, penup, speed, and hideturtle.
Is there any way of disabling screen updates until the drawing is finished, then manually updating the canvas, with RawTurtle?
The tracer() method is a method of the turtle's screen, not the turtle itself. To get access to it, when embedded under a tkinter window, wrap the canvas in a turtle screen:
screen = turtle.TurtleScreen(canvas)
t = turtle.RawTurtle(screen)
which should give you access to the various screen methods. Then you should be able to use screen.tracer(0) to turn off drawing updates and screen.update() to show the finished drawing. A more complete example:
import tkinter as tk
import turtle
root = tk.Tk()
canvas = turtle.ScrolledCanvas(root)
canvas.pack(side=tk.LEFT)
screen = turtle.TurtleScreen(canvas)
t = turtle.RawTurtle(screen)
t.hideturtle()
# t.speed('fastest')
screen.tracer(0)
t.penup()
t.sety(-100)
t.pendown()
t.circle(100)
screen.update()
screen.mainloop()

Application freezes after use of pandas and matplotlib modules

I wrote a script in python 3.4 where I'm making use of the tkinter module to build the GUI and pandas/matplotlib to visualise some data. The visualisation is being produced in a new window through the use of a button in the main window. The problem is that when I close the window that contains the graph (produced by pandas/matplot) the main window widgets are completely unresponsive. Furthermore, when I try to close the main window (through the 'X' button) I get a Fatal Python error: PyEval_RestoreThread: NULL tstate, which I don't get if I close the window without producing the graphs.
In simple words: the rest of the application behaves as it should if I never produce the graphs and becomes completely unresponsive if I do.
Below are the code segments of the caller of the plotting method in the main window and the method itself where the use of pandas and matplot is clearly shown.
Caller:
button_view_browsers = tk.Button(window, text="Display graph", command=lambda: self.threaded_browser_hist(doc))
button_view_browsers.grid(row=2, column=1, sticky=W+E+N+S, columnspan=3)
Visualisation method:
def display_browser_hist(self, data):
ser = Series(data.viewer_browser())
ser.value_counts().plot(kind='bar')
matplotlib.pyplot.show()
def threaded_browser_hist(self, doc):
Thread(target=self.display_browser_hist(doc)).start()
Any help would be greatly appreciated.
EDIT: Just to be sure I'm also including the modules I'm using and how I'm importing them:
from pandas import Series
import matplotlib
import tkinter as tk
from tkinter import W, E, N, S

Resources