_tkinter.TclError: image "\full\directory\link.gif" doesn't exist - python-3.x

I'm sorry to be a pain, and I know that there are god knows how many other questions referring to this 'image doesn't exist' tkinter error, however, none of the ones that I have found appear to have an issue with the entire directory, they all seem to just be referring to the file name only.
So, I'm trying to make a Logo Quiz, (I have removed some irrelevant code from the example because otherwise it will be too long to place here..)
However, when I try to show the logo, it tells me that the image doesn't exist.
Showing me an issue with the entire directory link, of which if I copy directly from the error and place into Windows Explorer, opens the image perfectly fine.
Here's the code:
from tkinter import *
import tkinter.messagebox
import random
from PIL import Image, ImageTk
import os
class Window(Frame):
global questionstart
def questionstart():
if gameplayvar == 0:
chosenlinknumber = random.randint(0, len(templist)-1)
chosen = templist[chosenlinknumber]
temp = chosen.split("\\")
temp2 = temp[2].split(".")
temp3 = temp2[0].split("L")
global directory
quizlogo_label = Label(root, image = directory)
quizlogo_label.grid(row=1, column=2)
root = Tk()
root.geometry("900x590")
root.iconbitmap(r'\\replacing\the\server\directory\Documents\pythontests\Logos\logoquizlogo_YVp_icon.ico')
C = Canvas(root, bg="blue", height=500, width=500)
possiblelinks = [
'\\NewLogos\AdobeLogo.gif',
'\\NewLogos\AmazonLogo.gif',
'\\NewLogos\AppleLogo.gif',
'\\NewLogos\BMWLogo.gif',
'\\NewLogos\ChromeLogo.gif',
'\\NewLogos\DebianLogo.gif',
'\\NewLogos\DiscordLogo.gif',
'\\NewLogos\FirefoxLogo.gif',
'\\NewLogos\GoogleLogo.gif',
'\\NewLogos\MicrosoftLogo.gif',
'\\NewLogos\OperaLogo.gif',
'\\NewLogos\PhotoshopLogo.gif',
'\\NewLogos\PlayStationLogo.gif',
'\\NewLogos\PythonLogo.gif',
'\\NewLogos\TwitterLogo.gif',
'\\NewLogos\VisualStudioCodeLogo.gif',
'\\NewLogos\WindowsLogo.gif'
]
templist = possiblelinks
chosenlinknumber = random.randint(0, len(templist)-1)
chosen = templist[chosenlinknumber]
p1 = '\\replacing\the\server\directory\Documents\pythontests'
directory = p1+chosen
app = Window(root)
root.mainloop()
And this is what is returned when I run it:
"C:\Program Files (x86)\Python36-32\python.exe" "//replacing/the/server/directory/Documents/pythontests/tkinterimagetry1.py"
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files (x86)\Python36-32\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "//replacing/the/server/directory/Documents/pythontests/tkinterimagetry1.py", line 143, in quizstart
questionstart()
File "//replacing/the/server/directory/Documents/pythontests/tkinterimagetry1.py", line 121, in questionstart
quizlogo_label = Label(root, image = directory)
File "C:\Program Files (x86)\Python36-32\lib\tkinter\__init__.py", line 2760, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "C:\Program Files (x86)\Python36-32\lib\tkinter\__init__.py", line 2293, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: image "\\replacing\the\server\directory\Documents\pythontests\NewLogos\DiscordLogo.gif" doesn't exist
I don't have a clue what is causing it to not find the file as the directory that is being giving out as an error works perfectly fine in Windows Explorer..
Thanks,
Xan

this is the problematic part:
global directory
quizlogo_label = Label(root, image = directory)
the Label constructor expects the image to be passed in as an ImageTk Instance, not a string containing the filename.
it needs to be something like:
global directory
self.photo = Image.PhotoImage(directory)
self.image = ImageTk.PhotoImage(self.photo)
quizlogo_label = Label(root, image = self.photo)
note that both instances of image classes as assigned as attributes of self which is the instance of Window so that they are not garbage collected when the function exits

Related

Pygtk Liststore most recent call last after Liststore update

I created simple code in PyGtk that displays a list of names. After clicking the Update button, the list of names will be updated. Unfortunately, I can't get rid of the "most recent call last" error that appears after clicking the Update button. Can anyone advise me on the problem? This is probably a problem with a line of code under "# select and row".
EDIT:
Script returns error message:
Traceback (most recent call last):
File "/home/radek/Desktop/stackowr1.py", line 18, in choiceRow
line = model[treeiter][0]
File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 849, in __getitem__
aiter = self._getiter(key)
File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 837, in _getiter
aiter = self.get_iter(key)
File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 871, in get_iter
path = self._coerce_path(path)
File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 846, in _coerce_path
return TreePath(path)
File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 1210, in __new__
path = ":".join(str(val) for val in path)
TypeError: 'NoneType' object is not iterable
My code:
```python
# -*- coding: utf-8 -*-
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class MyWindow(Gtk.Window):
def __init__(self):
super(MyWindow, self).__init__()
self.set_border_width(3)
self.set_default_size(800, 600)
self.name1 = "John"
self.name2 = "George"
def choiceRow(selection):
model, treeiter = selection.get_selected()
line = model[treeiter][0]
print(line)
def update_name(self):
self.name1 = "Jeane"
self.name2 = "Margot"
print(self.name1, self.name2)
win.liststore.clear()
win.liststore.append([self.name1])
win.liststore.append([self.name2])
button = Gtk.Button(label = "Update")
button.connect("clicked", update_name)
self.layout = Gtk.Layout()
self.tree = Gtk.TreeView()
self.liststore = Gtk.ListStore(str)
self.tree.set_model(self.liststore)
self.liststore.append([self.name1])
self.liststore.append([self.name2])
render = Gtk.CellRendererText()
self.column = Gtk.TreeViewColumn("ID", render, text=0)
self.tree.append_column(self.column)
# select a row
selectetRow = self.tree.get_selection()
selectetRow.connect("changed", choiceRow)
self.layout.put(self.tree, 0,0)
self.layout.put(button, 0,100)
self.add(self.layout)
win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
Gtk.TreeSelection.get_selected returns None when nothing is selected, after the update call there's nothing selected so you get None for treeiter and you try to access model[None][0] which obviously must fail. You need to check whether the returned iter is valid before trying to use it so just change your choiceRow function to
def choiceRow(selection):
model, treeiter = selection.get_selected()
if treeiter:
line = model[treeiter][0]
print(line)

My text doesn't show up in a new window, what could be the problem?

I'm writing a code that solves sudoku's. When I open a new window (with toplevel), it doesn't show any text on it. I get an error but I don't know what it means? Can anybody please help me?
import tkinter
from tkinter import messagebox
from tkinter import *
from tkinter.ttk import *
from winsound import *
rootdescription = tkinter.Tk()
rootdescription.geometry("800x800")
rootdescription['cursor'] = 'tcross'
rootdescription.title("Sudoku Solver - Description")
def inputwindow():
inputwindow = tkinter.Toplevel()
inputwindow.geometry("800x800")
inputwindow['cursor'] = 'tcross'
inputwindow.title("Sudoku Solver - InputWindow")
I created my two windows as shown above.
startpage = Frame(rootdescription)
startpage.pack()
ins1page = Frame(rootdescription)
ins2page = Frame(rootdescription)
inputpage = Frame(rootdescription)
I didn't know if the information above was relevant but I posted it anyway.
Below you can find the code I used to create a button to the next window.
fill1 = tkinter.Button(inputpage, text="Fill the Sudoku in!", relief=GROOVE, font='courier 10', width=86, height=40,
command=lambda:[inputwindow(), rootdescription.withdraw()])
fill1.pack()
def on_enter(e):
fill1['background'] = 'black'
fill1['foreground'] = 'white'
def on_leave(e):
fill1['background'] = 'SystemButtonFace'
fill1['foreground'] = 'black'
fill1.bind("<Enter>", on_enter)
fill1.bind("<Leave>", on_leave)
rootdescription.mainloop()
inputwindow.mainloop()
The text below won't show up in the window, I really don't know why.
check = Frame(inputwindow)
cline1 = StringVar()
clabel1 = Label(inputwindow, textvariable=cline1, wraplength=700, font='courier 10')
cline1.set("_______________________________________________________________________________________")
clabel1.pack()
This is the error it gives me each time:
*** Remote Interpreter Reinitialized ***
Traceback (most recent call last):
File "\\V-FPS-01\Home-Edu$\93010858\Documents\informatica\Sudoku Solver.py", line 252, in <module>
rootdescription.mainloop()
File "C:\Program Files\Python38\lib\tkinter\__init__.py", line 1420, in mainloop
self.tk.mainloop(n)
KeyboardInterrupt
I changed the order of the last two pieces of code, it now looks like this:
check = Frame(inputwindow)
cline1 = StringVar()
clabel1 = Label(inputwindow, textvariable=cline1, wraplength=700, font='courier 10')
cline1.set("_______________________________________________________________________________________")
clabel1.pack()
rootdescription.mainloop()
inputwindow.mainloop()
I get another error now but I still don't know how to solve my problem.
Currently the error looks like this:
Traceback (most recent call last):
File "\\V-FPS-01\Home-Edu$\93010858\Documents\informatica\Sudoku Solver.py", line 252, in <module>
check = Frame(inputwindow)
File "C:\Program Files\Python38\lib\tkinter\ttk.py", line 740, in __init__
Widget.__init__(self, master, "ttk::frame", kw)
File "C:\Program Files\Python38\lib\tkinter\ttk.py", line 557, in __init__
tkinter.Widget.__init__(self, master, widgetname, kw=kw)
File "C:\Program Files\Python38\lib\tkinter\__init__.py", line 2561, in __init__
BaseWidget._setup(self, master, cnf)
File "C:\Program Files\Python38\lib\tkinter\__init__.py", line 2530, in _setup
self.tk = master.tk
AttributeError: 'function' object has no attribute 'tk'
I thought that the program confused the names of the window and the function (because the are the same), but changing them doesn't seem to make any difference.
Here is a runnable code:
import tkinter
from tkinter import messagebox
from tkinter import *
from tkinter.ttk import *
from winsound import *
rootdescription = tkinter.Tk()
rootdescription.geometry("800x800")
rootdescription['cursor'] = 'tcross'
rootdescription.title("Sudoku Solver - Description")
def inputwindowf():
inputwindow = tkinter.Toplevel()
inputwindow.geometry("800x800")
inputwindow['cursor'] = 'tcross'
inputwindow.title("Sudoku Solver - InputWindow")
inputpage = Frame(rootdescription)
inputpage.pack()
fill1 = tkinter.Button(inputpage, text="Fill the Sudoku in!", relief=GROOVE, font='courier 10', width=86, height=40,
command=lambda:[inputwindowf(), rootdescription.withdraw()])
fill1.pack()
def on_enter(e):
fill1['background'] = 'black'
fill1['foreground'] = 'white'
def on_leave(e):
fill1['background'] = 'SystemButtonFace'
fill1['foreground'] = 'black'
fill1.bind("<Enter>", on_enter)
fill1.bind("<Leave>", on_leave)
rootdescription.mainloop()
inputwindow.mainloop()
check = Frame(inputwindow)
cline1 = StringVar()
clabel1 = Label(inputwindow, textvariable=cline1, wraplength=700, font='courier 10')
cline1.set("_______________________________________________________________________________________")
clabel1.pack()
The last 6 lines need to go on the new window; inputwindow.

NameError: name 'Ptime' is not defined using tkinter scale scroller

I'm trying to create a function to modify the timecode shift of a script for instant replay, but when I create the function including the variable mentioned by Tkinter, I'm getting a name not defined error. I used a software called "PAGE" to create the GUI so I really have a very basic knowledge of tkinter. I'm not quite sure what code I need to include so I'm just going to paste all of the function definition and the entire support script generated by PAGE
I moved all of my function definitions into the support script but to no avail
def set_Tk_var():
global Ptime
Ptime = tk.DoubleVar()
global Pspeed
Pspeed = tk.StringVar()
text = "play: timecode: 00:00:0" + str(Ptime) + ";00 \\nc"
def IRplay():
print('testguiPAGE_support.IRplay')
session.write(b"stop\n")
session.write( text.encode() )
sys.stdout.flush()
in the main script the only place it's being referred to is:
def vp_start_gui():
global val, w, root
root = tk.Tk()
testguiPAGE_support.set_Tk_var()
top = Toplevel1 (root)
testguiPAGE_support.init(root, top)
root.mainloop()
w = None
def create_Toplevel1(root, *args, **kwargs):
global w, w_win, rt
rt = root
w = tk.Toplevel (root)
testguiPAGE_support.set_Tk_var()
top = Toplevel1 (w)
testguiPAGE_support.init(w, top, *args, **kwargs)
return (w, top)
getting error
Traceback (most recent call last):
File "C:\Users\InstSmart\Desktop\Rplay\Outputs\testguiPAGE.py", line 23, in <module>
import testguiPAGE_support
File "C:\Users\InstSmart\Desktop\Rplay\Outputs\testguiPAGE_support.py", line 40, in <module>
text = "play: timecode: 00:00:0" + str(Ptime) + ";00 \\nc"
NameError: name 'Ptime' is not defined
if there is anymore info you need, comment it, and I will add to the question

Animating a gif W/O using PIL

I am currently trying to make life easier by having the code pull all the frames into my code and execute the animation. My current code is:
import time
from tkinter import *
import os
root = Tk()
imagelist = []
for file in os.listdir("MY-DIRECTORY"):
if file.endswith(".gif"):
imagelist.append(PhotoImage(file=str(os.path.join("MY-DIRECTORY", file))))
# extract width and height info
photo = PhotoImage(file=imagelist[0])
width = photo.width()
height = photo.height()
canvas = Canvas(width=width, height=height)
canvas.pack()
# create a list of image objects
giflist = []
for imagefile in imagelist:
photo = PhotoImage(file=imagefile)
giflist.append(photo)
# loop through the gif image objects for a while
for k in range(0, 1000):
for gif in giflist:
canvas.create_image(width / 2.0, height / 2.0, image=gif)
canvas.update()
time.sleep(0.1)
root.mainloop()
When I try to execute the file it gives me this error which I cannot make sense of.
Traceback (most recent call last):
File "C:/Users/Profile/Desktop/folder (2.22.2019)/animation2.py", line 21, in <module>
photo = PhotoImage(file=imagelist[0])
File "C:\Users\Profile\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 3545, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "C:\Users\Profile\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 3501, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't open "pyimage1": no such file or directory
Note: I am adapting this code to fit my needs I did not write it.
I ran some print statements to verify the pyimage was being uploaded to the array but I cannot figure out why its saying there is no such file or directory if its already uploaded to the array. Can you all please shine some light.
I found that I was creating an unnecessary array of objects lower in the code. giflist[]. I ultimately resolved the issue by removing it and having the loop use the array that was created earlier in the code imagelist. The following code works now.
import time
from tkinter import *
import os
root = Tk()
imagelist = []
for file in os.listdir("My-Directory"):
if file.endswith(".gif"):
imagelist.append(PhotoImage(file=str(os.path.join("My-Directory", file))))
# Extract width and height info
photo = PhotoImage(file="My-Directory")
width = photo.width()
height = photo.height()
canvas = Canvas(width=width, height=height)
canvas.pack()
# Loop through the gif image objects for a while
for k in range(0, len(imagelist)):
for gif in imagelist:
canvas.create_image(width / 2.0, height / 2.0, image=gif)
canvas.update()
time.sleep(0.1)
root.mainloop()

How to make functions that draw lines in canvas (tkinter 3.x) properly

I am making a program that draws a line(you decide where is the beggining and end of it with the sliders/scales), problem is im getting these errors(That i wish i understood) when i press the psy Button(code below the errors) :
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\python351\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:/Users/Koteu/PycharmProjects/guji/fsd.py", line 23, in creat
cans.create_line(ar1,ar2,br1,br2)
File "C:\python351\lib\tkinter\__init__.py", line 2331, in create_line
return self._create('line', args, kw)
File "C:\python351\lib\tkinter\__init__.py", line 2319, in _create
*(args + self._options(cnf, kw))))
_tkinter.TclError: bad screen distance ".14855536.14855504"
Process finished with exit code 0
anyways, the code :
import os
import sys
from tkinter import *
root = Tk()
app=Frame(root)
root.geometry("1200x1200")
ar1 = Scale(root,from_=0,to=600)
ar2= Scale(app,from_=0,to=600,deafultvar=0)#app instead of root because the button for unknown to me reason
#wouldn't appear in GUI otherwise
br1= Scale(root,from_=0,to=600)
br2= Scale(root,from_=0,to=600)
cans = Canvas(root,width = 500,height = 500)
cans.create_line(600,50,0,50) #This has nothing to do with the actual program by my understanding
def creat():
cans.create_line(ar1,ar2,br1,br2)#< this is what causes the problem i don't understand
psy=Button(root,command=creat,text="karole")
psy.pack()
cans.pack()
ar1.pack()
ar2.pack()
br1.pack()
br2.pack()
mainloop()
also, if that helps, im using py345
cans.create_line(x0, y0, ...) takes an even number of integer coordinates as positional args. You passed widgets, which were turned into their string identifiers. In ".14855536.14855504", '.' represents root, '14855536' is the canvas, and '14855504' is the scale ar1. Instead you need to use the .get() method on the scales to get their integer values. The following works.
from tkinter import *
root = Tk()
root.geometry("1200x1200")
ar1 = Scale(root,from_=0,to=600)
ar2= Scale(root,from_=0, to=600)
br1= Scale(root,from_=0, to=600)
br2= Scale(root,from_=0, to=600)
cans = Canvas(root, width=500, height=500)
def creat():
cans.create_line(ar1.get(), ar2.get(), br1.get(), br2.get())
psy=Button(root, command=creat, text="karole")
ar1.pack()
ar2.pack()
br1.pack()
br2.pack()
psy.pack()
cans.pack()
root.mainloop()
A couple of other fixes: the defaultvar option is not valid and caused an error; mainloop() instead of root.mainloop() caused tk to create a second Tk object, which is a bad idea.
EDIT: added the code that works.

Resources