0

The following code works correctly in MS Windows (the script exits when pressing q):

import Tkinter as tk

class App():
    def __init__(self):
        self.root = tk.Tk()
        self.root.geometry("{0}x{1}+0+0".format(
            self.root.winfo_screenwidth(), self.root.winfo_screenheight())
        )
        self.root.overrideredirect(True)
        tk.Label(text="some text here").grid()
        self.root.bind('q', self.appexit)
        self.root.mainloop()

    def appexit(self, event):
        self.root.destroy()

App()

I tried to run it in a "window manager-less" Debian environment (boot to console, run startx, which launches the script via .xinitrc (the only command there)).

The script starts as expected but pressing q does not do anything (I was expecting X to close and return to the text console). I later tried to add just in case self.root.focus() before the mainloop() but it did not help.

What could be the reason of this different behavior between the MS Windows and Debian environment?

WoJ
  • 27,165
  • 48
  • 180
  • 345

3 Answers3

1

With overrideredirect program loses connection with window manage so it seems that it can't get information about pressed keys and even it can't be focused.

MS Windows is one big window manager so it seems that overrideredirect doesn't work on that system.

Maybe you could use self.root.attributes('-fullscreen', True) in place of self.root.overrideredirect(True)


BTW: for testing I use self.root.after(5000, self.root.destroy) - to kill window after 5s when I can't control it.


EDIT:

Some (working) example with fullscreen.

With overrideredirect on Linux program can get keyboard events so binding doesn't work, and you can't focus Entry(). But mouse and Button() works. overrideredirect is good for "splash screen" with or without buttons.

import Tkinter as tk

class App():
    def __init__(self):
        self.root = tk.Tk()

        # this works

        self.root.attributes('-fullscreen', True)

        # this doesn't work

        #self.root.overrideredirect(True)
        #self.root.geometry("800x600+100+100") # to see console behind
        #self.root.after(5000, self.appexit) # to kill program after 5s

        self.root.bind('q', self.q_pressed)

        tk.Label(text="some text here").grid()
        e = tk.Entry(self.root)
        e.grid()
        e.focus() # focus doesn't work with overrideredirect 

        tk.Button(self.root, text='Quit', command=self.appexit).grid()

        self.root.mainloop()

    def q_pressed(self, event):
        print "q_pressed"
        self.root.destroy()

    def appexit(self):
        print "appexit"
        self.root.destroy()

App()
furas
  • 134,197
  • 12
  • 106
  • 148
  • Thanks but this unfortunately does not change the behaviour (the key binding still does not work in Debian) – WoJ Dec 01 '13 at 09:25
  • I used overrideredirect on windows with keypresses and it worked. https://github.com/niccokunzmann/cannon – User Dec 01 '13 at 12:21
  • @Woj do you have problem with `.attributes('-fullscreen', True)` or still trying `overrideredirect` ? Keybinding will not works with overrideredirect. – furas Dec 01 '13 at 17:13
  • @User have you try it on Linux ? – furas Dec 01 '13 at 17:39
  • @furas: I tried your version but it did not change anything (= nothing happens when pressing `q`). I asked a friend of mine to run it on a Mandriva/Red Hat machine to test as well. It may be very well that the lack of window manager is causing this, I will check by firing up one when back home) – WoJ Dec 02 '13 at 08:14
  • @furas no, I did not try overrideredirect on linux – User Dec 02 '13 at 15:33
  • @WOJ I add example - I run it on Linux Mint (based on Ubuntu/Debian). But I said before program with `overrideredirect` doesn't get information about pressed keys so it doesn't know that `q` was pressed and it doesn't know that it has to run binded function. – furas Dec 02 '13 at 18:54
  • Thanks - it works! It was indeed `-fullscreen` which should have been used – WoJ Dec 07 '13 at 13:33
1

If a key binding doesn't work, it is likely that the window to which the binding is associated doesn't have the keyboard focus. In your situation with no window manager, your program probably doesn't have keyboard focus.

You might try forcing it to have focus with root.focus_force(). This will sometimes give focus to a window even when the application as a whole isn't the foreground app. This is somewhat depending on the window manager, or lack thereof.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
-1

This usually works for me:

def appexit(self, event):
    self.root.quit() # end mainloop
    self.root.destroy()
User
  • 14,131
  • 2
  • 40
  • 59