I am writing a program in Python 3.10 on a W11 machine to do things with a large collection of images. The images are divided into categories. Each category is treated slightly differently and there is a front end menu to select the category and import the relevant module. Each module is written as a stand alone .py file. My problem is that although the modules run well as stand alone files, when imported I get an error "tkinter.TclError: image "pyimage1" doesn't exist". Two bits of hopefully minimum reproducible examples are included; Universal Viewer test.py which is the menu script and Art_Viewer_test which is imported as a module. Pointers to the error would be appreciated.
MENU CODE
'''
from tkinter import *
import sys
root = Tk()
root.attributes("-fullscreen", True)
root.configure(bg="black")
def q_key_pressed(event):
if root.attributes("-fullscreen")==False:
root.attributes("-fullscreen", True)
else:
root.attributes("-fullscreen", False)
sys.exit()
def act_on_selection(x):
if x==1:
import Art_Viewer_test
opening_menu_frame=Frame(root,bg="black",relief='flat',bd=0, highlightthickness=0)
text_for_heading='\n\n\n\n\n\n\nIMAGE VIEWER\n\n\n'
heading=Label(opening_menu_frame,bg='black',fg='lightgray',font=
("Arial","16"),text=text_for_heading,bd=0)
heading.pack()
art = Button(opening_menu_frame,pady=15,borderwidth=0,text="Art Images",font=
("Arial","16"),bg='black',fg='white',command=lambda:
act_on_selection(1))
art.pack()
inst_text='\n\n\n\n\n\n\nClick one of the catagories or Q to exit the program'
instruction=Button(opening_menu_frame,borderwidth=0,text=inst_text,font=
("Arial","16"),bg='black',fg='white')
instruction.pack()
opening_menu_frame.pack()
root.bind("q",q_key_pressed) and root.bind("Q",q_key_pressed)
root.mainloop()'''
MODULE CODE
'''
from tkinter import *
from PIL import ImageTk,Image
root = Tk()
def right_key_pressed():
#do stuff
pass
control_frame=Frame(root,bg="lavender",relief='flat', borderwidth=40)
control_frame.pack()
image=Image.open("icons/next.gif")
nexticon = ImageTk.PhotoImage(image)
nextimageclick=Button(control_frame,image=nexticon, text
="next",compound="bottom",command=right_key_pressed)
nextimageclick.pack()
root.mainloop()
'''
Related
I'm trying to show and hide a png (With no frame, margin, or title bar) but can't find a good way to do it. I tried using matplotlib but the code has to be in the main thread so I can't figure out how to use functions to show or hide it. I also tried tkinter but ran into the same problem where calling it from a function the code would just stop when trying to call it from a function.
Is there a simple way to accomplish this?
Below is what I am trying to accomplish though the code doesn't display any image. The code doesn't return an error either, it just stops executing at mainloop without displaying anything unless the code is in the main thread.
#Import modules
import os #For working directory
from pynput import keyboard #For hotkeys
from tkinter import *
from PIL import ImageTk,Image
#Set default directory
os.chdir('C:\\Users\\Username\\Desktop\\Python')
#Define global variables
global img
#Functions
def ExitProgram():
print('test')
#sys.exit(0)
quit() #Will not work in production, switch to sys.exit
return
def ShowImage():
root = Tk()
canvas = Canvas(root, width=300, height=300)
canvas.pack()
img = ImageTk.PhotoImage(Image.open("menu.png"))
canvas.create_image(20, 20, anchor=NW, image=img)
root.overrideredirect(True) # removes title bar
root.mainloop()
print('test')
return
#Define hotkeys
with keyboard.GlobalHotKeys({
'<ctrl>+q': ExitProgram,
'<ctrl>+0': ShowImage}) as h:
h.join()
I tried to make a module in which I made a funtion which just reads and display the image in GUI. Then I made another module which makes call to that function when the button is clicked. Button gives me error.
#module code:
from tkinter import *
class disp:
def __init__(self):
root1.geometry("400x500")
image = PhotoImage(file = 'png2.png')
Label(root1,image=image).pack()
root1.mainloop()
#main code:
from tkinter import *
import testimg as ti
def click():
ti.disp()
root = Tk()
Button(text = 'Click me',command=click).pack()
root.mainloop()
In your class disp, you have put the master as root1 whereas in the main code, you have defined Tk() as root. This means that root1 is no window so the label that has a master of root1 has no where to pack itself.
You also need to remove root1.mainloop() because it’s useless and causing errors due to the fact that root1 doesn’t have Tk(). It’s like trying to loop a while statement without typing in while. This gives an error.
Below modified code is based on yours:
#module code:
from tkinter import *
class disp:
def __init__(self):
root1 = Tk()
root1.geometry("400x500")
image = PhotoImage(master=root1, file='png2.png') # set master to root1
Label(root1, image=image).pack()
root1.mainloop()
But using multiple Tk() instances is not a good design.
I have been using tkinter to supply a file dialog (in python 3.6) which allows users to select a directory. It works fine when it is a sub-function within the same module, but if I move that subfunction into a separate module and then try to import it from that module, it no longer works. Instead the code just hangs when the file dialog should pop up but it never appears.
working code:
This works if I run the main function
from tkinter import Tk
from tkinter.filedialog import askdirectory
def SelectDirectory():
# start up the tk stuff to have a file directory popup
print('start')
root = Tk()
print('postroot')
root.withdraw()
print('postwithdraw')
# let the user pick a folder
basepath = askdirectory(title='Please select a folder')
print('postselection')
root.destroy()
print('postdestroy')
return basepath
def main():
ans = SelectDirectory()
print(ans)
If I instead put this in another module and import it from that module, then it will print until 'postwithdraw' and then just hang.
submod.py:
from tkinter import Tk
from tkinter.filedialog import askdirectory
def SelectDirectory():
# start up the tk stuff to have a file directory popup
print('start')
root = Tk()
print('postroot')
root.withdraw()
print('postwithdraw')
# let the user pick a folder
basepath = askdirectory(title='Please select a folder')
print('postselection')
root.destroy()
print('postdestroy')
return basepath
and then run this:
from submod import SelectDirectory
def main():
ans = SelectDirectory()
print(ans)
It never gets past 'postwithdraw' and the file dialog never pops up.
Does anyone know what I am doing wrong here? I would think it has something to do with the tkinter window not appearing since its not the main module but is there some way to get past that?
Your both versions don't work. Both give 'module' object is not callable.
You have to use
root = Tk.Tk()
instead of
root = Tk()
and then both versions works.
Maybe two Tk in Tk.Tk() seems weird but usually we use lowercase tk instead of Tk in
import tkinter as tk
and then you have
root = tk.Tk()
I am doing GUI programming using Tkinter on Python. I am using the grid manager to make widgets. I have created several buttons and I want to upload an image on top of them. When I enter this code, it gives me an escape sequence error.
I heard using PIL is not a good idea? Is that true?
cookImage = PhotoImage(file = "image/C:\Users\terimaa\AppData\Local\Programs\Python\Python36-32\cook.gif")
Windows filenames must be entered as raw strings:
cookImage = PhotoImage(file=r"C:\Users\terimaa\AppData\Local\Programs\Python\Python36-32\cook.gif")
This applies to all of Python, not just PIL.
Use:
path = r"a string with the path of the photo"
Note the r prefix, it means a raw string.
...
img = ImageTk.PhotoImage(Image.open(file=path))
label = tk.Label(root, image = img)
label.something() #pack/grid/place
...
The path can be:
Absolute ("C:\Users\terimaa\AppData\Local\Programs\Python\Python36-32\cook.gif")
Relative ("\cook.gif", depends on where the Python code is)
If you have an image file that is exactly what you want, just open it with BitmapImage or PhotoImage. Note that Tcl/Tk 8.6, which you should have with 3.6 on Windows, also reads .png files. On Windows, prefix the filename with 'r' or use forward slashes: 'C:/User/...'.
The actual PIL package is no longer maintained and only works on 2.x. That is what a new user should not use. The compatible successor, pillow (installed for instance with python -m pip install pillow) is actively maintained and works with 3.x. The compatibility extends to the import statement: import PIL imports pillow. Pillows allows one to manipulate images and to convert many formats to tk format (the ImageTk class).
this is exact code which is most help for move image
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
import os, shutil
class Root(Tk):
def __init__(self):
super(Root,self).__init__()
self.title("thinter Dialog Widget")
self.minsize(640,400)
self.labelFrame = ttk.LabelFrame(self,text="Open A File")
self.labelFrame.grid(column=0,row=1,padx= 20, pady= 20)
self.btton()
def btton(self):
self.button = ttk.Button(self.labelFrame, text="Browse Afile", command=self.fileDailog)
self.button.grid(column=1,row=1)
def fileDailog(self):
self.fileName = filedialog.askopenfilename(initialdir = "/", title="Select A File",filetype=(("jpeg","*.jpg"),("png","*.png")))
self.label = ttk.Label(self.labelFrame, text="")
self.label.grid(column =1,row = 2)
self.label.configure(text = self.fileName)
os.chdir('e:\\')
os.system('mkdir BACKUP')
shutil.move(self.fileName,'e:\\')
if __name__ == '__main__':
root = Root()
root.mainloop()
you could not move image to c drive due to Permission denied: this code work successfully on python 3.8, 3,7
Below is my code. The code is from within a different program, so a button would be clicked
on another program and initiate this code.I have been struggling with this a while, in short i am trying to a) take an image, save it to a directory, b) display the image on canvas or root a long with a button named "refresh". When refresh is clicked then remove is called deleting the 'file' first taken, takes another picture and refreshes the canvas with the second picture taken and so on and on. I am not seeming to get it to work in this sequence and have used multiple examples etc etc. Can anyone assist please, is my design incorrect perhaps? I have ample other code but the code below details only one function calling global properties etc etc. I would appreciate an answer but also want to learn from the answer to understand what is being done wrong.
import os
import sys
import time
from VideoCapture import Device
impot Image
from PIL import ImageTk, Image
from Tkinter import *
import Tkinter
root = Tk()
root.wm_title("Camera Capture")
root.resizable(0,0)
root.geometry("600x400")
path = ('C:\Users\Public')
os.chdir(path)
def take_picture():
global root
global path
os.chdir(path)
cam = Device()
cam.saveSnapshot('pic.gif')
webcam_pic = Tkinter.PhotoImage(file='./pic.gif')
item = Label(root, anchor = W, image = webcam_pic)
item.pack()
button_take_picture = Button(root, text = "Take picture", command = take_picture(), bg
= 'blue')
button_take_picture.place(relx = .9, rely = .5, anchor = "center")
mainloop()
actually the command should be without this '()'
command =take_picture
button_take_picture = Button(root, text = "Take picture", command = take_picture, bg=blue')