2

I am developing an GUI using python tkinter in debian based linux.

Whenever I am removing root and toplevel window title bar using overrideredirect(True) method I am facing below mentioned problems.

  1. Entry field not working(not getting focus/not getting input) when I am clicking on it.
  2. Whenever I use Alt+Tab key then only it get focused.
  3. Then I have to keep pressed mouse left or right button on clicked position then only entry field accept input otherwise input is written on terminal window.

Could any one suggest an alternative way to remove titlebar or to hide title bar in tkinter on linux based system.This code runs well on windows system.

There is a question Tkinter's overrideredirect prevents certain events in Mac and Linux which seems same as my problem but I could not getting its solution .

from tkinter import *

class GuiApp:
    def __init__(self,master):
        master_frame = Frame(master,background= 'blue')
        master_frame.grid()
        b1 = Button(master_frame,
                      height=3,text="BUTTON",width=15, font=14,command=lambda parent=master: self.create_top_window(parent))
        b1.grid(row=0, column=0, pady=3, padx=5)
        master_frame.grab_set()

    def create_top_window(self,parent):
        toplevel = Toplevel(parent, bg='red', bd=5, relief=RIDGE)
        toplevel.geometry('350x250')
        toplevel.wm_overrideredirect(True)
#       toplevel.wm_attributes('-type','splash')
        label=Label(toplevel,text='Entry:')
        entry=Entry(toplevel,width=10,font=13)
        button = Button(toplevel, text='close', font=('TkTextFont', 14), command=toplevel.destroy)
        label.grid(row=0,column=0,padx=5,pady=5)
        entry.grid(row=0,column=1,padx=5,pady=5)
        button.grid(row=1, column=0, padx=1, pady=1)
        toplevel.grab_set()

root = Tk()
root.wm_overrideredirect(True)
#root.wm_attributes('-type','splash')
app = GuiApp(root)
root.mainloop()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
ARYA1992
  • 131
  • 4
  • 16

2 Answers2

2

The titlebar is provided by the window manager. When you set the overrideredirect flag you are asking the window manager to ignore your window which doesn't just remove the decorations. However, the Extended Window Manager Hints protocol allows you to specify the intended type of a window (menu, splash, dialog etc) and offers a way to hint to the window manager so that it can provided suitable decoration. In this case it sounds like a splash screen so you might try using "splash" as a window type:

self.wm_attributes('-type', 'splash')

The 'type' attribute is only provided when the Tk windowing system is 'x11'. The splash hint should get rid of the window manager decoration for you although this depends on the window manager configuration.

patthoyts
  • 32,320
  • 3
  • 62
  • 93
0

Way too late to the party, but I was experiencing a very similar problem in Linux until I figured out a quite inelegant solution. So if anyone stumbles upon something similar in the future, here's an awful way to circumvent this problem.

To be more precise, my problem was: Entries don't work on windowless tk.Tk or tk.TopLevels in Linux (whether I use overridedirect(True) or any other windowless type from wm_attributes (("-type", "splash") or any other)).

In my case, I noticed that the entries weren't working because I was minimizing the windowed root window before launching the windowless TopLevel... BUT, if the windowed root window was lying behind the windowless TopLevel, the entries worked fine (try to say this paragraph quickly out loud).

My solution: create a transparent windowed root window to stay always behind the windowless TopLevel. Ain't that both awful and cute?

Here are four examples of things that don't work for me on Linux (problem replication), and my very ugly final solution:

Example 1:


import tkinter as tk

root = tk.Tk()
root.geometry("+%d+%d" % (root.winfo_screenwidth() // 2, root.winfo_screenheight() // 2))
root.wm_attributes("-type", "splash")

entry = tk.Entry(root, text="bla bla bla")
entry.pack()

root.mainloop()

Example 2:


import tkinter as tk

root = tk.Tk()
root.geometry("+%d+%d" % (root.winfo_screenwidth() // 2, root.winfo_screenheight() // 2))
root.overrideredirect(True)

entry = tk.Entry(root, text="bla bla bla")
entry.pack()

root.mainloop()

Example 3:


import tkinter as tk

root = tk.Tk()
root.iconify()

toplevel = tk.Toplevel(root)
toplevel.geometry("+%d+%d" % (root.winfo_screenwidth() // 2, root.winfo_screenheight() // 2))
toplevel.wm_attributes("-type", "splash")

entry = tk.Entry(toplevel, text="bla bla bla")
entry.pack()

root.mainloop()

Example 4:


import tkinter as tk

root = tk.Tk()
root.iconify()

toplevel = tk.Toplevel(root)
toplevel.geometry("+%d+%d" % (root.winfo_screenwidth() // 2, root.winfo_screenheight() // 2))
toplevel.overrideredirect(True)

entry = tk.Entry(toplevel, text="bla bla bla")
entry.pack()

root.mainloop()

My Ugly Solution:


import tkinter as tk

root = tk.Tk()
root.wait_visibility(root)
root.attributes('-alpha', 0)

toplevel = tk.Toplevel(root)
toplevel.geometry("+%d+%d" % (root.winfo_screenwidth() // 2, root.winfo_screenheight() // 2))
toplevel.overrideredirect(True)

entry = tk.Entry(toplevel, text="bla bla bla")
entry.pack()

root.mainloop()

This is just a simple example, but you can make both windows (the invisible one and the windowless TopLevel) match position, size and behavior at all times to sustain the charade (with small additional tricks here and there).

Anyways, I hope this helps anyone.

peputito
  • 13
  • 3