how to insert buttons on the west side an Image file on the East Side or simply as a background using Tk - python-2.7

Here is my script
# Python 2.7.14 version
from Tkinter import *
import Tkinter
import tkMessageBox
from urllib2 import urlopen
import PIL
from PIL import ImageTk
import ImageTk
FILENAME = 'Fleur_de_lys.jpg'
root = Tk()
background = Canvas(root, width=250, height=250)##AttributeError: class Tk has no attribute 'Canvas'
canvas.pack()
tk_img = ImageTk.PhotoImage( file = FILENAME)
canvas.create_image(125, 125, image=tk_img)
quit_button = tk.Button(root, text = "Quit", command = root.quit, anchor = 'w',
width = 10, activebackground = "#33B5E5")
quit_button_window = canvas.create_window(10, 10, anchor='nw', window=quit_button)
root.mainloop()
No matter what attempt I do I keep getting AttributeError: class Tk has no attribute 'Canvas' where is my error if I just create button I have no issue what so ever all work but when I attempt to have a background image everything does not work

The problem appears to be that you're creating a canvas, and storing it in a variable named background, yet the very next line you are trying to call something called 'canvas', which you've never created.
Change this:
background = Canvas(root, width=250, height=250)
canvas.pack()
...
canvas.create_image(125, 125, image=tk_img)
to this:
background = Canvas(root, width=250, height=250)
background.pack()
...
background.create_image(125, 125, image=tk_img)

I fixed the issue jpg image was not being accepted I made it with a gif. Also found how to correct the buttons location and posn.
Here is the example without all the program
canvas = Canvas(root, width = 500, height = 500, bg='black')
canvas.pack(expand=YES, fill=BOTH)
my_image = PhotoImage(file='C:\\MOTD\\fleur_de_lys.gif')
canvas.create_image(0, 0, anchor = NW, image=my_image)
b1 = Button(root, text="From the Commander", command=callback,anchor = 'w',
width = 18, activebackground = "#33B5E5")
button_window1 = canvas.create_window(10, 10, anchor='nw', window=b1)

Related

Nested frames in tkinter

Good Day,
Using tkinter, Python 3.5
I am attempting to create nested frames using for loops and lists to generate the frame names.
This works for the first level of frames within a frame, however the next level fails.
For example, this code works:
from tkinter import *
from tkinter import ttk
frameLevel1List = ['Frame1', 'Frame2', 'Frame3', 'Frame4']
frameLevel2List = ['FrameA', 'FrameB', 'FrameC', 'FrameD']
class myUI:
def __init__(self):
#create main window & frames
self.main_window = Tk()
self.main_window.title("frame2 UI V001 ")
self.main_window.configure(background='gray')
w=750
h=500
x=100
y=100
self.main_window.geometry("%dx%d+%d+%d" % (w, h, x, y))
self.userlabel = Label(self.main_window, bg='gray', fg='white', text = "user Label")
self.userlabel.pack(side="top")
self.levellabel = Label(self.main_window, bg='gray', fg='white', text = "level Label")
self.levellabel.pack(side="top")
#create bottom frame
bottomFrame = Frame(self.main_window, bg='white', height=500, width=800)
bottomFrame.pack(side=BOTTOM)
#create frames from first list
for frame in frameLevel1List:
self.frame=Frame(bottomFrame, width=800, height = 100, bg = 'green', highlightbackground="black", highlightcolor="black", highlightthickness="1")
self.frame.pack(side="top")
self.framelabel = Label(self.frame, bg='blue', fg='white', text = frame)
self.framelabel.place(x=10, y=10)
mainloop()
UI=myUI()
However, when I add a second for loop to add the second list of frames within each of the first frames, I get an error. The following code fails
from tkinter import *
from tkinter import ttk
frameLevel1List = ['Frame1', 'Frame2', 'Frame3', 'Frame4']
frameLevel2List = ['FrameA', 'FrameB', 'FrameC', 'FrameD']
class myUI:
def __init__(self):
#create main window & frames
self.main_window = Tk()
self.main_window.title("frame2 UI V001 ")
self.main_window.configure(background='gray')
w=750
h=500
x=100
y=100
self.main_window.geometry("%dx%d+%d+%d" % (w, h, x, y))
self.userlabel = Label(self.main_window, bg='gray', fg='white', text = "user Label")
self.userlabel.pack(side="top")
self.levellabel = Label(self.main_window, bg='gray', fg='white', text = "level Label")
self.levellabel.pack(side="top")
#create bottom frame
bottomFrame = Frame(self.main_window, bg='white', height=500, width=800)
bottomFrame.pack(side=BOTTOM)
#create frames from first list
for frame in frameLevel1List:
self.frame=Frame(bottomFrame, width=800, height = 100, bg = 'green', highlightbackground="black", highlightcolor="black", highlightthickness="1")
self.frame.pack(side="top")
self.framelabel = Label(self.frame, bg='blue', fg='white', text = frame)
self.framelabel.place(x=10, y=10)
#create frames from second list
for frame2 in frameLevel2List:
self.frame2=Frame(frame, width=800, height = 50, bg = 'yellow')
self.frame2.pack(side="top")
self.frame2label = Label(self.frame2, bg='blue', fg='white', text = frame2)
self.frame2label.place(x=10, y=10)
mainloop()
UI=myUI()
Here is the error message:
Traceback (most recent call last):
File "C:\Users\Nicholas Boughen\Desktop\py\rubrics\nestedFramesTest.py", line 43, in <module>
UI=myUI()
File "C:\Users\Nicholas Boughen\Desktop\py\rubrics\nestedFramesTest.py", line 36, in __init__
self.frame2=Frame(frame, width=800, height = 50, bg = 'yellow')
File "C:\Users\Nicholas Boughen\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 2584, in __init__
Widget.__init__(self, master, 'frame', cnf, {}, extra)
File "C:\Users\Nicholas Boughen\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 2132, in __init__
BaseWidget._setup(self, master, cnf)
File "C:\Users\Nicholas Boughen\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 2110, in _setup
self.tk = master.tk
AttributeError: 'str' object has no attribute 'tk'
Anything that could help me understand what I have done wrong and create nested frames with for loops would be most appreciated.
Perhaps there's a completely different way of procedurally creating nested frames that would be better? What I'm trying to do is to generate the frame names from a list and change the interface as the list changes. So if more or fewer items are in the list, there will be more or fewer frames in the interface. The list will be edited from a different interface.
lor
After many more hours of researching other people who had similar issues, and #jasonharper comment, I have discovered that I need to save(append) the frame ID into a list as it is created, to ensure each widget remains unique.
Here is the code that does what I want it to do:
from tkinter import *
import functools
class practice:
def __init__(self,root):
self.frame_list = []
for w in range(5):
frame = Frame(root, width=800, height = 100, bg = 'green', highlightbackground="black", highlightcolor="black", highlightthickness="1")
frame.pack(side="top")
self.frame_list.append(frame)
for w in range(5):
frame = Frame(root, width=400, height = 50, bg = 'blue', highlightbackground="black", highlightcolor="black", highlightthickness="1")
frame.pack(side="top")
self.frame_list.append(frame)
for w in range(5):
frame = Frame(root, width=200, height = 25, bg = 'yellow', highlightbackground="black", highlightcolor="black", highlightthickness="1")
frame.pack(side="top")
self.frame_list.append(frame)
print('button list is', self.frame_list)
root = Tk()
root.title("frame2 UI V001 ")
root.configure(background='gray')
w=750
h=500
x=100
y=100
root.geometry("%dx%d+%d+%d" % (w, h, x, y))
Thank you, I will attempt to post questions with greater clarity in future.
lor

Exception AttributeError: when I try to get Tkinter to refresh image

I'm new to Tkinter, but I want to have my jpg image refreshed every 5 second, I've made this code, but I'm getting an exception attribute error.
can someone guide me ??
I receive this error:
Exception AttributeError: "'PhotoImage' object has no attribute '_PhotoImage__ph
oto'" in <bound method PhotoImage.__del__ of <PIL.ImageTk.PhotoImage object at 0
x754b16f0>> ignored
# -*- coding: utf-8 -*-
from Tkinter import *
from apscheduler.schedulers.background import BackgroundScheduler
from PIL import ImageTk, Image
import time
window = Tk()
scheduler = BackgroundScheduler()
a = 0
def readimage():
global a, img, img1, img2, imglab
a = a +1
img = Image.open("./web1.jpg")
img1 = img.resize((288, 162), Image.ANTIALIAS)
img2 = ImageTk.PhotoImage(img1)
readimage()
window.attributes('-fullscreen', True)
window.configure(background = "black")
endbutton = Button(window, text="exit", command=window.destroy)
endbutton.grid(row=1,column=1, sticky="nw")
alabel = Label(window, text=a)
alabel.grid(row=2, column=2, sticky="w")
imglab = Label(window, image=img2, bg="black",fg="white", font=("Arial", 18))
imglab.place(relx=.6, rely=1.0,anchor="sw")
imglab.lower()
window.update()
scheduler.add_job(readimage, 'interval', seconds=5)
scheduler.start()
while True:
time.sleep(1)
alabel[ "text"]=a
imglab[ "image"]=img2
window.update()
mainloop()

Tkinter remove stored file from memory

from Tkinter import *
import Tkinter as tk
import ttk
import tkFileDialog
import numpy as np
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
class Look():
def __init__(self, master):
self.master = master
self.master.title("Demo")
self.master.configure(background = "grey91") #the color will be changed later
self.master.minsize(500, 300) # width + height
self.master.resizable(False, False)
self.top_frame = ttk.Frame(self.master, padding = (10, 10))
self.top_frame.pack()
ttk.Button(self.top_frame, text = "Load file", command = self.load_file,
style = "TButton").pack()
ttk.Button(self.top_frame, text = "Reset", command = self.clear_file,
style = "TButton").pack()
ttk.Button(self.top_frame, text = "Plot", command = self.plot_file,
style = "TButton").pack()
self.bottom_frame = ttk.Frame(self.master, padding = (10, 10))
self.bottom_frame.pack()
self.fig = plt.figure(figsize=(12, 5), dpi=100) ##create a figure; modify the size here
self.fig.add_subplot()
plt.title("blah")
self.canvas = FigureCanvasTkAgg(self.fig, master = self.bottom_frame)
self.canvas.show()
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.bottom_frame)
self.toolbar.update()
self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
def load_file(self):
self.file = tkFileDialog.askopenfilename(defaultextension = ".txt", filetypes = [("Text Documents", "*.txt")])
def clear_file(self):
self.fig.clf()
self.fig.add_subplot()
plt.xticks()
plt.yticks()
self.canvas.draw()
def plot_file(self):
self.r, self.g = np.loadtxt(self.file).transpose()
self.fig.clf()
plt.plot(self.r, self.g)
self.canvas.show()
def main():
root = Tk()
GUI = Look(root)
root.mainloop()
if __name__ == "__main__": main()
The code above creates a program has three buttons. The Load file buttom loads a txt file, Reset button is supposed to clear the plot and delete the file just loaded into the memory. Plot button is to plot the figure onto canvas below.
I have a question about how to write function associated with Reset function, i.e. clear_file function. Currently what it does is just clear the plot from canvas. But it seems the file that has been loaded to plot is stored in memory, since click again Plot, it will display the plot. My goal is to use Reset button to bring it to a fresh start--nothing stored in memory. I know loading a new file will overwrite the previous file. But when there are multiple buttons for loading different files, the situations could become complicated. Therefore I hope Reset can do the job.
If you want to try this little program, you may create a simple txt with two column data to be loaded into the program.
Thanks.
I would make 2 changes. Move the code that sets up your plot into its own method and reset the frame each time the method is called. This can be done with destroying the frame and remaking it. The 2nd change I would change the command on your reset to reference this new method.
Taking your code this is what I would change to be able to reset the plot.
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import filedialog
import numpy as np
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
class Look():
def __init__(self, master):
self.master = master
self.master.title("Demo")
self.master.configure(background = "grey91") #the color will be changed later
self.master.minsize(500, 300) # width + height
self.master.resizable(False, False)
self.top_frame = ttk.Frame(self.master, padding = (10, 10))
self.top_frame.pack()
ttk.Button(self.top_frame, text = "Load file", command = self.load_file,style = "TButton").pack()
ttk.Button(self.top_frame, text = "Reset", command = self.new_plot,style = "TButton").pack()
ttk.Button(self.top_frame, text = "Plot", command = self.plot_file,style = "TButton").pack()
self.bottom_frame = ttk.Frame(self.master, padding = (10, 10))
self.bottom_frame.pack()
self.new_plot()
# this function will reset your plot with a fresh one.
def new_plot(self):
self.bottom_frame.destroy()
self.bottom_frame = ttk.Frame(self.master, padding = (10, 10))
self.bottom_frame.pack()
self.fig = plt.figure(figsize=(12, 5), dpi=100) ##create a figure; modify the size here
self.fig.add_subplot()
plt.title("blah")
self.canvas = FigureCanvasTkAgg(self.fig, master = self.bottom_frame)
self.canvas.show()
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.bottom_frame)
self.toolbar.update()
self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
def load_file(self):
self.file = filedialog.askopenfilename(defaultextension = ".txt", filetypes = [("Text Documents", "*.txt")])
def clear_file(self):
self.fig.clf()
self.fig.add_subplot()
plt.xticks()
plt.yticks()
self.canvas.draw()
def plot_file(self):
self.r, self.g = np.loadtxt(self.file).transpose()
self.fig.clf()
plt.plot(self.r, self.g)
self.canvas.show()
if __name__ == "__main__":
root = tk.Tk()
GUI = Look(root)
root.mainloop()

Image does not display in tkinter Canvas

I am trying to create a new class of Canvas that will be able to display and resize images. However The image does not display. I searched for similar questions and all the answers said to keep a reference of the PhotoImage in the class.( This answer for example). I tried doing that in a number of ways and none worked. In this example I tried saving a reference in a dictionary. I also tried self.tkimage = ImageTk.PhotoImage(image=img) which didn't work. And also tried using globals. I assume it has something to do with the garbage collector, but don't know how to solve.
Please assist.
import Tkinter as tk
from PIL import ImageTk, Image
import numpy as np
# a subclass of Canvas
class MyCanvas(tk.Canvas):
def __init__(self,parent,**kwargs):
tk.Canvas.__init__(self,parent,**kwargs)
self.tkimg = {}
self.images = []
self.image_on_canvas = []
def my_create_image(self, *args, **kw):
img = kw['image']
self.images.append(img)
self.tkimg[img] = ImageTk.PhotoImage(image=img)
kw['image'] = self.tkimg[img]
item = self.create_image(*args, **kw)
self.image_on_canvas.append(item)
def main():
root = tk.Tk()
myframe = tk.Frame(root)
myframe.pack(fill=tk.BOTH, expand=tk.YES)
mycanvas1 = MyCanvas(myframe, width=850, height=400, bg="red", highlightthickness=0)
mycanvas2 = MyCanvas(myframe, width=850, height=400, bg="green", highlightthickness=0)
mycanvas1.pack(side=tk.LEFT, fill=tk.BOTH, expand=tk.YES)
mycanvas2.pack(side=tk.RIGHT, fill=tk.BOTH, expand=tk.YES)
# add some widgets to the canvas
mycanvas2.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
mycanvas2.create_rectangle(50, 25, 150, 75, fill="blue")
arr1 = np.random.random([256,256])*255
img1 = Image.fromarray(arr1)
mycanvas1.my_create_image(0, 0, image=img1, anchor=tk.NW)
root.mainloop()
if __name__ == "__main__":
main()

How to deselect checkboxes using a button in python?

I need to have a button which clears selected check boxes. Please anyone guide me. Thanks in advance.
import Tkinter
from Tkinter import*
top = Tkinter.Tk()
CheckVar1=IntVar()
CheckVar2=IntVar()
C1=Checkbutton(top, text = "Music", variable = CheckVar1,
onvalue = 1, offvalue = 0, height=5,
width = 20,activebackground="red",bg="green")
C2=Checkbutton(top, text = "Video", variable = CheckVar2,
onvalue = 1, offvalue = 0, height=5,
width = 20)
C1.pack()
C2.pack()
B = Tkinter.Button(top, text ="Hello",activebackground="red",
,bd=3,bg="green",width=5) #Button
B.pack()
top.mainloop()
Create a function that will set the value of CheckVar1 and CheckVar2 to 0.
def clear():
CheckVar1.set(0)
CheckVar2.set(0)
And then just link it with the button.
B = Tkinter.Button(top, text ="Hello",activebackground="red",
bd=3,bg="green",width=5, command = clear) #Button
BTW, you had an extra comma here.