I'm writing a program where most of user interaction happens in Windows Command line, however I use Tkinter for some File and Directory selection dialogs.
When I start up program by clicking .py file (In IDLE the problem doesn't occur), command line is launched and when Tk root window is instantiated, it takes over the focus from command line, even if I withdraw it.
This behaviour requires extra action from user to focus back on command line window.
Here is some code sample to reproduce the problem.
from tkinter import Tk
root_window = Tk()
root_window.withdraw()
name = input("Enter your name:\n")
print("Nice to meet you, " + name)
How do I keep Windows Command line in focus?
Strange enough, now your example works for me in the intended way - even though, ten minutes ago, it showed the problem you have reported. The only other thing I tried out inbetween was to add a latency to the withdraw call:
root_window.after(1, lambda: root_window.withdraw())
It seemed to also work as intended with a latency argument of zero, but now I am not sure what exactly changed the behaviour.
Related
I'm a newbie in programming and I'm struggling a bit (a lot actually) with my first "program". Here's what I did:
since I want the code not to be too long, I want to split it in two files. In the first one I call the main window, where I put a button. If I click this button, I run the second script, that should hide the main window and make appear a new window (toplevel). The problem is that if I click the button nothing happens.
A thing I noticed is that if in the second script I add the strings "if name=="main": main.mainloop()", then this new window does appear, but a second main window appears too, as if I re-runned the main code.
Script one:
from tkinter import *
import os
main=Tk()
def sw():
os.system("python3 ./script_two.py")
my_button=Button(main,text="NEW",command=sw)
my_button.grid(row=0,column=0)
if__name__="__main__":
main.mainloop()
Script two:
from tkinter import *
import os
import script_one
script_one.main.withdraw()
second_window=Toplevel()
def Close():
second_window.destroy()
script_one.main.deiconify()
second_button = Button(second_window,text="Exit",command=Close)
second_button.grid(row=0,column=0)
If I put together the scripts (inserting the code of "script_two" in 'def sw()'), I get exactly what I want, but if I split them as showed, I get the problem.
Obviously for a code this short it would be easier and faster to write a single script, what I actually have is a longer code, but the problem is the same.
Any idea? Thank you very much
I am trying to write a Bash script so that I can run my program on a double click. The program uses tkinter and the GUI is the only thing I need to see. My bat file is the following:
python BudgetGUI.py &
This runs the code and successfully prints any print statements I have throughout my code but it never opens up the GUI. It simply runs through and closes immediately.
How can I modify the bash script to run the GUI?
Thanks in advance!
Edit Solutions for both mac and pc would be great, though at the moment I am on PC. I am working in Python3.
You need to add a call to mainloop(). I can't say for sure without seeing your code, but probably you need to add root.mainloop() to the bottom.
You don't need a bash or bat file. For your mac, just add a shebang and make the file executable. For Windows, add a shebang and associate the file with py.exe.
If you want to suppress the command line from popping up along with the GUI, rename your file with a .pyw extension.
Make the window made with tkinter stay out of IDLE*
if you have
root = Tk()
at the end put
root.mainloop()
if you have another name for that like:
window1 = Tk()
then, at the end put
window1.mainloop()
and so for any name you gave to the istance of Tk()
A little example
import tkinter as tk
class Window:
root = tk.Tk()
label = tk.Label(root, text = "Ciao").pack()
app = Window()
app.root.mainloop()
Python 2
The code above is for python 3.
For python 2 you just need to change the first line (Tkinter with T, not t)
import Tkinter as tk
I am making a simple program that also incorporates the use of TKinter. The inclusion is to have it copy and paste to my clipboard and also to check the contents of my keyboard. However, without much change from me, the console spits out an error :
can't invoke "event" command: application has been destroyed while executing
"event generate $w <<ThemeChanged>>" (procedure "ttk::ThemeChanged" line 6)
invoke from within "ttk::ThemeChanged"`
My questions:
I do not understand what the error means;
I do not understand how to fix it.
From my understanding, these error usually pop up from the use of matplotlib, which I am not using. The python console still can function after this message but it is annoying and distracting.
here is the code that i think is affecting it.
from Tkinter import Tk
r = Tk()
r.withdraw()
r.clipboard_clear()
r.clipboard_append(finalbib)
r.destroy()
#os.startfile("TEMPPY.py")
clipbardtest=True
while clipbardtest:
r=Tk()
clippytest = r.clipboard_get()
r.destroy()
if clippytest==finalbib:
os.system('cls')
print "Successfully copied to clipboard"
#os.remove("TEMPPY.py")
clipbardtest=False
morebibdef()
else:
time.sleep(1.2)
#os.startfile("TEMPPY.py")
r = Tk()
r.withdraw()
r.clipboard_clear()
r.clipboard_append(finalbib)
r.destroy()
See one of the comments from this question
If you use this in a console script this might lead to an error, that
the .destroy() function will not work ("can't invoke "event" command:
application has been destroyed while executing [...]"). To prevent
this, call r.update() before r.destroy.
The error means that all of the tkinter windows have been destroyed, but that something is trying to generate an event. In order to generate an event you must have a window.
I have a wxPython gui that sometimes has weird behavior. I have a button that creates a dialog, then calls dia.Show() and dia.Center(). At this point dia.IsShownOnScreen, dia.IsActive, and dia.Shown are all "true", but the dialog is actually nowhere to be found.
Does anyone know any reasons why IsShownOnScreen would come up as true, but be incorrect?
I am trying to isolate this problem in the code, but the codebase is large and this problem may take a while to reproduce.
Any help is appreciated.
Edit:
If the following code is not run while initializing, my dialog window shows up without a problem:
TEXT="choose directory. No spaces are allowed in path!"
dia = wx.DirDialog(self, message=TEXT,defaultPath = os.getcwd() ,style=wx.DD_DEFAULT_STYLE )
result=dia.ShowModal()
if result == wx.ID_OK:
self.WD=str(dia.GetPath())
dia.Destroy()
This piece of code is used if the user runs:
$ program.py
instead of specifying a directory in the command line:
$ program.py -WD directory
The code above has no obvious relationship to the button and dialog in the main frame of my gui, but this code is definitely what is breaking things.
I have written an application in python 2.7 and tkinter. I created a tool bar with several buttons that open up respective top windows that display various options. I used ttk.Checkbutton with the 'toolbutton' style as an indicator to show whether the option windows are open or closed.
The problem is that the option windows will go to the back if another window is selected. Currently, if one selects the toolbutton again, the option window will close. However, I only want to close the window if it is on top. If the option window is not on top, I want the window to moved to the front.
Some of the code I have working:
class MainWindow:
def __init__(self,application):
self.mainframe=tk.Frame(application)
application.geometry("900x600+30+30")
self.otherOptionsSelect=tk.IntVar()
self.otherOptions_Button=ttk.Checkbutton(application,style='Toolbutton',variable=self.otherOptionsSelect,
onvalue=1, offvalue=0,image=self.optionsIcon, command=self.otherOptions)
def otherOptions(self):
if self.otherOptionsSelect.get()==0:
self.otherOptions.destroy()
return
self.otherOptions=tk.Toplevel()
self.otherOptions.title("IsoSurface Options")
self.otherOptions.geometry("200x165+"+str(int(application.winfo_x())+555)+"+"+str(int(application.winfo_y())+230))
self.otherOptApply_button=ttk.Button(self.otherOptions,text="Apply",command=self.showFrame)
self.otherOptApply_button.place(x=20,y=80,width=50,height=30)
self.otherOptClose_button=ttk.Button(self.otherOptions,text="Close",command=self.otherOptionsClose)
self.otherOptClose_button.place(x=80,y=80,width=50,height=30)
def otherOptionsClose(self):
self.otherOptionsSelect.set(0)
self.otherOptions.destroy()
Here is a picture of the entire application I have written:
In the above image, each window has their respective ttk.checkbutton. At the moment, toggling the checkbutton either opens or closes the window. However, what I really want it to do is close the window if the window is in front of the application, or bring the window to the front if it is behind the application.
Hopefully this clears some things up.
Thanks in advance!
It is in fact possible to check stacking order of windows. Using Tkinter, you have to do some funny tcl evals to get at the information. I found the answer at TkDoc in the section on Windows and Dialogs, scroll down until you get to "Stacking Order". The code baffled me until I started playing around with it interactively. My test code was:
import Tkinter as tk
root = tk.Tk()
root.title('root')
one = tk.Toplevel(root)
one.title('one')
two = tk.Toplevel(root)
two.title('two')
I then manipulated the windows so that two was on top, one under that and root below them all. In that configuration, the following weirdness can tell you relative layering of windows:
root.tk.eval('wm stackorder '+str(two)+' isabove '+str(root))
returns 1, meaning "Yes, window two is above window root." While the following:
root.tk.eval('wm stackorder '+str(root)+' isabove '+str(two))
returns 0, meaning "No, window root is not above window two." You can also use the command:
root.tk.eval('wm stackorder '+str(root))
Which gives back the full window stacking order in the form of a weird string something like this:
'. .68400520L .68401032L'
Which starts to make sense when you run the commands:
str(root)
str(one)
str(two)
and figure out that root has the internal name '.', one is '.68400520L' and two is '.68401032L'. You read the output of root.tk.eval('wm stackorder '+str(root)) backwards so it's saying two is on top, one is under that and root is below both.