This is where the error is found:
global backbuttonimg
backbuttonimg = PhotoImage(file="backbutton.gif")
C6 = tkinter.Button(W_CheckDates, image=backbuttonimg, command = CheckDatesBack)
C6.pack()
I don't understand why this isn't working. I have another image in my program here:
def Login():
global W_Menu
W_Menu = Tk()
W_Menu.geometry('160x310+600+200')
W_Menu.title("NSS DB")
A0 = Canvas(W_Menu, width='160', height='160')
A0.pack()
global img
img = PhotoImage(file="nsslogo.gif")
A0.create_image(80,80, image=img)
I also get a similar error when I try to call the above definition after it has already been initially called (for example when my program logs out) so I have readjusted so the window simply deiconifies instead of calling it again, and I do not get the error again. However I am confused as to why I get an error with the former section of code now, as the button simply does not show up whether it is called for the first time or not. Sorry if this is a bit vague, please ask if I have not explained in enough detail. Thanks in advance.
P.S. I have looked in other threads with similar problems but none apply to me.
Ok so you say that the login function works once, then it can't work again. Here the problem can be solved using tk.Toplevel() instead of tk.Tk() see: why python photoimages don't exist? and tkinter.TclError: image "pyimage3" doesn't exist
These threads mention how you can't have two instances of Tk() running simultaneously, you have to use Toplevel() instead.
Why did these threads not apply to you (i think they do...)? But just a tip, if you state that they don't apply to you, then give reasons why, it helps make your question clearer. Also, add the full traceback when your question is about a particular error.
Hope this helps a bit.
Adding this for anyone who has tried the above with no success. If you have an erroneous path when running the script in some environments the path to the file is retained. I commented out everything from where I first use PhotoImage up to the window mainloop, run the script, close resulting gui, uncomment the code, run, and it shows the image as expected.
You can add a master parameter
backbuttonimg = PhotoImage(file="backbutton.gif",master=W_Menu)
Here Cledia
I am also facing this error.
And when I use Toplevel instead of To, it is working well
I suggest you to use TopleToplevel
Use tk.Toplevel() instead of tk.Tk() So its will work because the python coding library tkinter it doesnt make any sens if you make two windows working sametime with the tk.Tk() so you can use the toplevel() to open multiwindows in the same time !!
Hope it's Helpful
Related
I have a main program which does some cool stuff and I am currently setting up a 'settings editor' to let the user change some GUI related stuff and default values. It reads values from a text file, which is read in correctly and saves them to a dictionary self.propertiesDict. Some of the options are on/off switches, so I use checkbuttons for them. What is puzzling me is following behavior: the code works perfectly fine, when I execute the settingsEditor.py (the script creating the settings window) directly. All the checkbuttons are set to active / True. However, when I include my settingsEditor in my main program and call it, it creates fine but all the checkbuttons show the wrong value: False. I read a lot of topics here to find an answer, but I think I avoided the most common errors:
I use the tk variables
tk variables are created and set prior to the buttons
variables are not only in local scope (prefixed self.)
As you can see, I tried with an IntVar and a BooleanVar, but neither is working correctly. Something else is strange, when I use ttk.checkbuttons, I get the issue described here. I use Visual Studio for debugging and I can't see any difference in the process when going trough line by line, except for the wrong display result. I am happy for any suggestion. Sorry for not providing a full MWE, I will do, if nobody can help me from this here.
settingsEditor.py
import tkinter as tk
from tkinter import ttk
...
class mySettingsEditor:
def __init__(self):
...
def createGUI(self):
# Show main options on startup on/off
self.showOptionsVar = tk.IntVar()
self.showOptionsVar.set(str2int(self.propertiesDict['showMainOptionsExpanded']))
print(self.showOptionsVar.get())
self.checkBtn1 = tk.Checkbutton(Frame, text='Main Options Section', variable=self.showOptionsVar)
self.checkBtn1.grid(column=0,row=2)
# Show main STL section on startup on/off
self.showMainSTLVar = tk.BooleanVar()
self.showMainSTLVar.set(str2bool(self.propertiesDict['showMainSTLSectionExpanded']))
print(self.showMainSTLVar.get())
self.checkBtn2 = tk.Checkbutton(Frame, text='Main STL Section', variable=self.showMainSTLVar)
self.checkBtn2.grid(column=0,row=3)
main.py
from settingsEditor import mySettingsEditor
...
settEditor = mySettingsEditor()
This is how it looks in the GUI when executed separately (terminal with print output to the left):
Thats the result when I add it in main.py. The boxes are unchecked, but .get() tells me the values are correctly assigned to the tk variables.
As suggested by jasonharper, switching to Toplevel() for the child windows fixed the issue. Thanks alot!
This is my first post here, but I cannot find a solution elsewhere.
I'm using Python's Tkinter library to create a minimal Hashcat GUI Hash-Cracker, just for fun :)
It takes in a .hccapx hash file and a .dict dictionary file from sub-directories added to Hashcat-5.1.0 on Windows 10.
My issue is marked here:
def browsehccapx():
if path.exists(".\selected.hccapx"):
os.remove(".\selected.hccapx")
else:
pass
hccapxpath = filedialog.askopenfilename(initialdir=".\hccapxfiles", title="Select handshake .hccapx file",filetypes=((".hccapx files","*.hccapx"),("all files","*.*")))
hccapxpath = shutil.copy(hccapxpath, rootdir)
os.rename("{}".format(hccapxpath), ".\selected.hccapx")
and this is the Entry box that wont display the variable hccapxpath:
hccapxpathtxt = Entry(window, textvariable=hccapxpath, width=64, bg="white")
Can someone tell me why hccapxpathtxt will not display hccapxpath inside the Entry() box after browsehccapx() is called?
Do I need a different method to allow browsehccapx() to output the selected file path to the Entry() box?
Right now the program works perfectly fine when configured inside Hashcat directory, the only problem remaining is that the .hccapx file and .dict wordlist file are not displayed once selected.
All help is greatly appreciated! So is constructive criticism! Thank you in advance to everyone who takes time to try to help :)
The full python file can be found here: https://pastebin.com/6GQxSxfb
I fixed it. Thank you #acw1668. I defined hccapxpath as a StringVar() under global variables, then ran the following updated function to get the Entry() box to display the path:
def browsehccapx():
if path.exists(".\selected.hccapx"):
os.remove(".\selected.hccapx")
else:
pass
fullhccapxpath = filedialog.askopenfilename(initialdir=".\hccapxfiles", title="Select handshake .hccapx file",filetypes=((".hccapx files","*.hccapx"),("all files","*.*")))
fullhccapxpath = shutil.copy(fullhccapxpath, rootdir)
hccapxpath.set(fullhccapxpath)
os.rename("{}".format(fullhccapxpath), ".\selected.hccapx")
The pastebin link is good for 6 months.
I hope this helps others with a similar issue in the future!
I'm currently working on a GUI using Tkinter and Python. One of the windows I create has two buttons on it: one to restart a separate python script and the other one to shut down the whole program.
When I hit the "restart" button, I'd like it to run the restart code, and then destroy the window that has the two buttons on it. I saw something else on SO that let you run two commands at once through a button click but I can't seem to get it to work. Right now the code for the button is:
buttonRestart = Button(restartWindow, text = "Restart", width = 8,
height=3, command = lambda: self.restartExternal() and
restartWinow.destroy)
When executed, it seems that the restartExternal code is working, but it doesn't destroy the window as well. Any suggestions would be greatly appreciated!
Just create a method that calls the two methods. Tere's no shame in creating an extra function for this. It's a much more maintainable solution that trying to cram a bunch of code into a lambda.
def on_restart(self):
self.restartExternal()
self.restartWinow.destroy()
buttonRestart = Button(..., command = self.on_restart)
Instead of self.restartExternal() and restartWindow.destroy you could do [self.restartExternal(), restartWindow.destroy()]. This way, it will call restartWindow.destroy() whatever self.restartExternal() returns, whereas how it is, if self.restartExternal() returns False, Python doesn't even check to see if restartWindow.destroy is True or False. Besides that, restartWindow.destroy isn't even called in yours, because you left out the parentheses.
The answer proposed by Bryan looks reasonable, but with minimum changes - you can feed the list of functions to lambda function, like this:
buttonRestart = Button(restartWindow, text = "Restart", width = 8,
height=3, command = lambda: [self.restartExternal(),
restartWinow.destroy()] )
In my opinion, it looks better for two functions, at least.
My company is using Python 2.6 (yuck, I know, but it's my constraint). I need to make a little GUI that involves a ComboBox. I chose Tix, because that's what I have--not allowed to grab anything else.
Anyway, I'd like to set the label that the ComboBox has to the top side. According to the documentation at http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixComboBox.htm, if I use "labelside" in the ComboBox constructor as a parameter, it should move the label to the top, like I want.
Unfortunately, when I do this, it gives me a strange error:
_tkinter.TclError: cannot assigned to static variable "-labelside"
CONTEXT: this is within a Python class that inherits from Tix.Frame. The first code example works perfectly, the other does not.
My constructor (not including 'labelside') looks like this:
combobox = Tix.ComboBox(self,
label="Available files: ",
selectmode='immediate',
dropdown=0,
editable=0,
variable=selectedfile,
options='listbox.height 5')
It works perfectly, as expected. I get a nice ComboBox in my window. The label is the left side, however--not what I want.
So, I try this:
combobox = Tix.ComboBox(self,
label="Available files: ",
labelside='top',
selectmode='immediate',
dropdown=0,
editable=0,
variable=selectedfile,
options='listbox.height 5')
That's when it gives me the error. I've scrounged the internet for answers, but have found only users who have the same unanswered question: why is it happening? It would appear that I'm following the documentation correctly.
I also tried substituting Tix.TOP for top, and it gave me the same error.
Any help or ideas would be greatly appreciated!
I'm writing an app that doesn't have a main window (it runs inside a Python interpreter in another app), and I thought I had a good solution for getting Tkinter to cooperate--I made the Tkinter.Tk class into a Borg.
class RootWindow(Tk):
""" Invisible window that serves as the default parent
of all others.
"""
groupDict = {}
def __init__(self):
self.__dict__ = self.groupDict
if self.__dict__ == {}: # first instance
Tk.__init__(self)
self.withdraw()
Then I have my Windows, which are subclassed from Tkinter.Toplevel, default to parent=RootWindow(). The result should be that I can create any number of Windows and they'll use the same root.
It works once fine for the first Window, but after that things get all messed up. :(
see pic
What am I doing wrong? Is this even a feasible solution?
Thanks
EDIT: I should add that even though there's other stuff running in the picture, the problem can be duplicated just by using RootWindow as the parent of a Tkinter.Toplevel.
EDIT: I overrode Window.mainloop so everything uses the RootWindow event loop.
def mainloop(self):
self.master.wait_window(self)
Then I create each visible window like this:
test = Window()
test.mainloop()
It seems to work because the windows do show up, but their contents are packed in an odd way that's hard to describe. It alternates between no contents at all and having everything squished horizontally and expanded vertically.
One problem appears to be that you are forgetting to start the event loop. Or, based on further edits of your question, you may be starting more than one main loop. You need exactly one main loop that is run from the root window.
Tkinter certainly allows an arbitrary number of top level windows, but your question doesn't appear to have enough details to show what is wrong unless my first guess is correct.