I am trying to follow along in the book Python Programming for Kids. I am working with a group of neighborhood kids and to reduce the cost we are using the Raspberry Pi as our computer. I am a Windows guy and the GUI builder of choice for me is WxPython. I am trying to get ready for next weeks class and have run into a problem. I have entered the code below
from tkinter import *
tk = Tk()
btn = Button(tk,text = 'click me')
btn.pack()
according to the book the second line is supposed to create a window (frame I think in the Wx world) and the third line defines a button object and the fourth inserts it in the window.
However, this is not working and I have not been able to figure out why. tkinter is imported and the tk object has lots of methods/properties visible when I type dir(tk) so I know that we have tkinter on the Pi's.
Any insight would be appreciated.
You have to run the windows system event loop and process events. This means the last command in your program should be tk.mainloop(). The X Windows System operated in a similar manner to Windows. The system dispatches event messages whenever something happens like the mouse moving, a button being clicked or a window needs redrawing and so on. On Windows you would have to 'pump the message queue' using GetMessage() and DispatchMessage(). With Tkinter this is handled in the mainloop() function (for both Windows and X).
Related
I'm learning Tkinter and just had a doubt.
Is there any method that prevents me from working with the window in the background until I close the main window? I saw that there is an argument about this here, but I ended up losing it and decided to ask.
Yes, it is possible (IIUC) and if I do understand correctly you simply want to block user for accessing other windows while your window is open. It has a slight flaw in that if user does a lot of alt-tabbing they may get keyboard focus on some other window but only the keyboard, as soon as they do anything with mouse they should get back to the main window. This can be handled using some module like keyboard to listen for global keyboard input but also perhaps it could be done using Windows API but for a tkinter only solution that is/should be effective enough you can use this:
import tkinter as tk
def check_focus():
if root.focus_get() is None:
root.focus_force()
root.after(100, check_focus)
def create_shield():
shield = tk.Toplevel(root)
shield.attributes('-topmost', True)
shield.attributes('-fullscreen', True)
shield.attributes('-alpha', 0.01)
shield.overrideredirect(True)
shield.bind('<FocusIn>', lambda _: root.focus_force())
root = tk.Tk()
root.attributes('-topmost', True)
create_shield()
check_focus()
root.mainloop()
First there is the after "loop" that checks for focus to see if the window has any, this prevents some attempts of trying to alt-tab away but enough attempts may cause some kind of timeout and the window will get out of focus.
The other part is a "shield" that simply is another fullscreen window that is almost completely invisible (on other OS the attribute name may be -splash instead of -alpha) and just keeps it in top to assist in focusing on the main window.
Or just make the window fullscreen and topmost (again the issues with keyboard focus on other windows but now user has no issues whatsoever with accessing the other windows except they wouldn't see what they are typing) and this requires to implement some button to close the window (currently doable by alt+f4 or shutting down the computer or killing the process via run without looking at what you are typing and perhaps some other way I haven't thought about, but for user convenience probably a button should be made that would simply destroy the window):
import tkinter as tk
root = tk.Tk()
root.attributes('-topmost', True)
root.attributes('-fullscreen', True)
root.mainloop()
Apologies if this has been asked before, but I couldn't find a clear answer. I'm writing a GUI to control a motor from a raspberry pi, and it's on a touchscreen. I've written some code which opens the built in matchbox keyboard when the Entry widget comes into focus, but this halts my entire tkinter window in the background, meaning that the user cannot see what they are entering appear in the Entry until they have closed the keyboard, and also that the screen often tears and looks horrible when it hangs in the background. Is there anyway to run this command:
def createNumpad(event=none):
os.system('matchbox-keyboard numpad')
so that the tkinter window doesn't freeze while the keypad is open? Thanks!
This is the relevant code from a SO answer changed to fit Tkinter:
import subprocess
def createNumpad(event)
try:
subprocess.Popen(["matchbox-keyboard", "numpad"])
except FileNotFoundError:
pass
def deleteNumpad(event):
subprocess.Popen(["killall","matchbox-keyboard"])
#
entry.bind("<Enter>", createNumpad)
entry.bind("<Leave>", deleteNumpad)
In Python with Tkinter, if you use the command:
`sometkapp.overrideredirect(True)`
It will make a Tkinter window that doesn't have a border from the window manager; however, at least on my windowing system, the Tkinter window then stays on top of all the other windows.
Is there a way to send a Tkinter window to the back, so that it always stays under all other open windows?
In some system window manager decides which window is on top or on bottom.
Using overrideredirect(True) you resign with its services - on some systems this meen no drawing border, no moving on top/on bottom (probably no refreshing window), no sending events (key pressed, mouse move).
I think you can do nothing with this using Tkinter or even pure Python. Maybe other module could do something.
I have a small GUI application that listens for network messages so a user can update some info and accept it. This is in a production factory environment and used for interacting with a specific piece of physical hardware (over serial in some cases). The workflow looks like this:
User is interacting with another program (5250 Green Screen)
They enter a certain keybinding that sends a UDP message to a Tkinter GUI
The Tkinter GUI does a deiconify()
User edits data, accepts (Enter) and it does an iconify()
My issue is that on windows XP, the GUI does not become active when I do the deiconify and conversely does not fall back to the prior window on iconify. I have tried some things I found in other questions such as:
Setting the Tk GUI as top.. self.wm_attributes("-topmost", 1)
Trying to set/force focus... self.focus_set() and self.focus_force()
Although the window is visible with the first, I can not seem to get it to be the active window so that the user can type in it without "clicking" on it to activate. The same is true for releasing the "focus" so that the active window becomes the one they were previously on (5250).
It seems like an issue that others also have had but I have not been able to find anything that works. Is there a programmatic way to get the window activated and release it when done?
Unfortunately, after a week there have been no answers and I was not able to find a direct way to do this with Tkinter. I did find a way to solve the problem though and it appears to work consistently. Here are the steps I took to make the screens activate:
Install pywin32.
Create a function that activates the tk app.
Create a function that activates the 5250.
Then each time I do a iconify/deiconify I also run the function to activate the appropriate screen. The code that activates the tk window looks like this:
def activate_self(self):
""" Activate this window. """
shell = win32com.client.Dispatch('WScript.Shell')
shell.AppActivate(str(self.title))
shell = None
The code that activates the caller is a little ugly since it has to guess the title but is the same basic concept.
I'm writing a program that uses the Tkinter widgets (ie. Frame, buttons, labels etc...) and everything works fine on my school computers (python 2.6 running on Ubuntu.), but on my Windows 7 computer at home, no error messages show up but the program doesn't open.
This is what I have written to set up the main frame:
from Tkinter import *
root = Tk()
mainframe = Frame(root)
mainframe.pack()
mainframe.grid()
The program then displays some labels and buttons (I don't believe that they're part of the problem). Again, the program works without any problems on my school computer which uses Python 2.6 and runs on Ubuntu. When I run the program at home, no error messages show up, but the Tkinter windows don't pop up.
Thanks!
Put this on the last line of youre program:
root.mainloop()
this will start the event loop and actually show you're window
that will probably fix the problem it worked on my computer
you do
from tkinter import *
root = Tk()
root.geometry('1000x1000')
root.mainloop()