I am using tkMessageBox.showinfo (info at tutorialspoint) to popup warnings in my program.
The problem happens only when the warning is called with a second TopLevel window (apart from the main one) on screen: in this case the warning remains hidden behind the second TL window.
I tried to call it thus:
tkMessageBox.showinfo(title='Warning',message=s).lift()
but it doesnt work. Any ideas?
I think the message box is only ever guaranteed to be above its parent. If you create a second toplevel and you want a messagebox to be on top of that second window, make that second window the parent of the messagebox.
tl2 = tk.Toplevel(...)
...
tkMessageBox.showinfo("Say Hello", "Hello World", parent=tl2)
I do not see the issue that you describe. The code I wrote below is just about the minimum needed to create a window which creates a second window. The second window creates an info box using the showinfo method. I wonder whether you have something besides this. (Note that I made the windows somewhat large in order to attempt cover up the info window.)
from Tkinter import Tk, Button, Toplevel
import tkMessageBox
top = Tk()
def make_window():
t = Toplevel(top)
t.title("I'm Window 2. Look at me too!")
B2 = Button(t, text = "Click me", command = hello)
B2.pack()
t.geometry('500x500+50+50')
def hello():
tkMessageBox.showinfo("Say Hello", "Hello World")
B1 = Button(top, text = "New Window", command = make_window)
B1.pack()
top.title("I'm Window 1. Look at me!")
top.geometry('500x500+100+100')
top.mainloop()
This was tested on Windows 7 (64-bit) using Python 2.7 (32-bit). It produces something like this:
Related
I'm somewhat new to python (started in Nov.) and after complete my first "program" I'm trying to built the GUI using Tkinter. I want to put the program on a Toplevel that I've created and have it run, but all Tkinter tutorials only talk about widgets and I don't know how to specify that a code should run on a specific Toplevel window. The best I can figure is to run the in the section where I define the Toplevel as shown in the example below, but that is not working.
from tkinter import *
import tkinter as tk
root=Tk()
root.geometry("500x200")
root.title('Test')
Label(root, text="Test").pack()
def test():
gen_win = Toplevel(root)
gen_win.title("Test")
gen_win.geometry("500x500")
Label(gen_win, text="Test").pack()
print(2+2)
btn_test=tk.Button(root, text="test", command=test).pack(fill=tk.X)
root.mainloop()
The example program (print(2+2)) doesn't print on the toplevel. Any ideas?
#jasonharper gave the correct answer:
"Code doesn't "run on a specific Toplevel window". It just runs, and if it happens to create a widget, or modify the contents of an existing widget, that change becomes visible as soon as your code returns to the mainloop. Label(gen_win, text=str(2+2)).pack() would be the simplest way to make your addition results visible in the window."
The code is simple. In tkinter I create a button which opens a new window. The difference in the pictures below might be hard to see but if you look closely you can see that in the first picture the root window is selected even though it's behind the new opened window.
In my actual program I use keybindings to operate the second window so it would be nice to instantly select this window so you don't have to click on it to use keys to operate it. How can I select the Toplevel window as soon as it opens?
from tkinter import *
def open_new_window():
top = Toplevel(root)
root = Tk()
Button(root, text="open new window", command=open_new_window).pack()
root.mainloop()
Possible duplicate of this question
Like acw1668 said, simply add top.focus() at the end of your function open_new_window
Your new open_new_window function will look like this:
def open_new_window():
top = Toplevel(root)
top.focus()
I read some tutorial (basic) on tkinter and learned how to create a mainloop and add gui elements to that. Also learned how to bind actions to button widgets.
Now I would like to do this:
launch the tkinter canvas
be able to read command from the console and update the canvas after those commands.
example:
I write command with arguments on the console and some graphics elements is being added to the canvas (and canvas is updated after).
Is something possible, maybe threding related?
Can you point me in one direction which you think is the most reasonable to follow?
Here's a simple demo of grabbing user input from the console via the standard input function. This technique is a little clunky, since we have to explicitly tell Tkinter to fetch the input string by clicking on a Button (or some other GUI event), but that might not be a big deal for your application.
import tkinter as tk
root = tk.Tk()
stuff = tk.StringVar()
display = tk.Label(root, textvariable=stuff)
display.pack()
def get_input():
s = input("CMD: ")
stuff.set(s)
tk.Button(root, text="Get input", command=get_input).pack()
root.mainloop()
When you click on the "Get input" Button, the "CMD: " prompt will be printed in the console window. Once the input is entered, the string is copied to the Label. Bad Thingsā¢ will happen if you click the button again before the input line is entered. :)
Came up with this:
from Tkinter import *
import random
root = Tk()
width = 800
height = 600
def key(event):
s = raw_input("CMD: ")
if s == 'quit':
root.destroy()
if s == 'l':
x1 = random.randint(0,width)
x2 = random.randint(0,width)
y1 = random.randint(0,height)
y2 = random.randint(0,height)
frame.create_line(x1,y1,x2,y2)
frame.focus_force()
frame = Canvas(root, width=width, height=height)
frame.bind("<Key>", key)
frame.pack()
frame.focus_set()
root.mainloop()
In this way it is a bit complicated because before entering something on the console I have to get the focus back clicking on its window. Maybe it would be nicer to read command from Tkinter directly and then opening dialogs for setting up command parameters.
I am building a notepad like application in tkinter-python. There is an option to change the font of the text writen in the text field of the application.
I have created a Font Chooser popup screen to be called from main window on clicking 'font' menu, which basically creates a FontChooser class object and passes to the main window, which sets the font in man window.
A sample of the code where font is getting set in main window is,
root = Tix.Tk(className="Notepad")
notepad = ScrolledText(root, width=100, height=100)
def open_font():
font = MyFont.askChooseFont(root)
notepad.tag_add("bt", "sel.first", "sel.last")
notepad.tag_config("bt", font=font.getFontTuple())
Now when I first run the application and select a portion of text and change the font, it works correctly. But after that, whatever portion of text I am selecting and changing the font, it is ignoring the selection and applying the font on the whole text. Can anyone let me know what is the problem here?
IDLE uses tag_config to syntax color python code and it works on all Python versions and major OSes for the last 15 years.
To have some idea of why it seems to fail for you, you need to find an MCVE that fails. Start without tix and scrollbars. (Tix is deprecated in 3.6 and bugs are not being fixed.) Also notice that your code uses the same tag for each selection, so that when you change the configuration, it applies to all previous selections.
Here is simplified code that works as intended and expected.
import tkinter as tk
import time
root = tk.Tk()
text = tk.Text(root)
text.pack()
text.insert('1.0', "line 1\nline 2\nline 3\n")
text.tag_add('bg', '1.0', '1.4')
text.tag_config('bg', background='red')
root.update()
time.sleep(1)
text.tag_add('bg', '2.0', '2.4')
text.tag_config('bg', background='blue')
root.update()
You could try modifying it step by step until it either reproduces your problem or does what you want.
EDIT with example modification: use 'sel.first' and 'sel.last' instead of hard-coded indexes.
import tkinter as tk
import time
root = tk.Tk()
text = tk.Text(root)
text.pack()
text.insert('1.0', "line 1\nline 2\nline 3\n")
root.update() # make text visible for selection
input('select some text')
text.tag_add('bg', 'sel.first', 'sel.last')
text.tag_config('bg', background='red')
root.update() # make change visible
input('select some text')
text.tag_add('bg', 'sel.first', 'sel.last')
text.tag_config('bg', background='blue')
root.update() # make 2nd change visible
input('look at result')
Run in console. Move tk window so console and GUI are both visible. Make selection as prompted. Click on console* and hit return to allow input statement to return. Repeat. The result for me is that both selections, but not everything, turns blue. I suggest changing font instead of bg color for the next experiment.
On Windows, the selection highlighting in the tk windows disappears when one clicks on the console because Windows only allows visible selection in one window at a time. However, the select markers are still present in the text widget so that tag_add still works.
Consider the following code snippet:
from tkinter import *
import tkinter.filedialog as fd
def mycallback(event):
fname = fd.askopenfilename()
print(fname)
root = Tk()
b1 = Button(root, text='Hello!')
b1.bind('<Button-1>', mycallback)
b1.pack()
root.mainloop()
After pressing the button b1 an open-dialog appears as supposed. If I press OK or CANCEL after choosing a file, the program crashes with exit code 139.
What's the problem here?
I'm using Python 3.4 on OS X 10.6.8.
Calling a function when clicking a button can be done using the button's callback argument.
So instead of binding <Button-1> to the button you should use
b1 = Button(root, text='Hello!', command=mycallback)
You should then also remove the event argument from the mycallback function, since command doesn't pass any arguments.
How this solves your problem, I really dont know. But according to your comment it does.
For more information on the Button (and any other) widget, see effbot.org