30

I have a python program which opens a new windows to display some 'about' information. This window has its own close button, and I have made it non-resizeable. However, the buttons to maximize and minimize it are still there, and I want them gone.

I am using Tkinter, wrapping all the info to display in the Tk class.

The code so far is given below. I know its not pretty, and I plan on expanding the info making it into a class, but I want to get this problem sorted before moving along.

Anyone know how I can govern which of the default buttons are shown by the windows manager?

def showAbout(self):


    if self.aboutOpen==0:
        self.about=Tk()
        self.about.title("About "+ self.programName)

        Label(self.about,text="%s: Version 1.0" % self.programName ,foreground='blue').pack()
        Label(self.about,text="By Vidar").pack()
        self.contact=Label(self.about,text="Contact: adress@gmail.com",font=("Helvetica", 10))
        self.contact.pack()
        self.closeButton=Button(self.about, text="Close", command = lambda: self.showAbout())
        self.closeButton.pack()
        self.about.geometry("%dx%d+%d+%d" % (175,\
                                        95,\
                                        self.myParent.winfo_rootx()+self.myParent.winfo_width()/2-75,\
                                        self.myParent.winfo_rooty()+self.myParent.winfo_height()/2-35))

        self.about.resizable(0,0)
        self.aboutOpen=1
        self.about.protocol("WM_DELETE_WINDOW", lambda: self.showAbout())
        self.closeButton.focus_force()


        self.contact.bind('<Leave>', self.contactMouseOver)
        self.contact.bind('<Enter>', self.contactMouseOver)
        self.contact.bind('<Button-1>', self.mailAuthor)
    else:
        self.about.destroy()
        self.aboutOpen=0

def contactMouseOver(self,event):

    if event.type==str(7):
        self.contact.config(font=("Helvetica", 10, 'underline'))
    elif event.type==str(8):
        self.contact.config(font=("Helvetica", 10))

def mailAuthor(self,event):
    import webbrowser
    webbrowser.open('mailto:adress@gmail.com',new=1)
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Vidar
  • 4,141
  • 5
  • 24
  • 30

5 Answers5

52

In general, what decorations the WM (window manager) decides to display can not be easily dictated by a toolkit like Tkinter. So let me summarize what I know plus what I found:

import Tkinter as tk

root= tk.Tk()

root.title("wm min/max")

# this removes the maximize button
root.resizable(0,0)

# # if on MS Windows, this might do the trick,
# # but I wouldn't know:
# root.attributes(toolwindow=1)

# # for no window manager decorations at all:
# root.overrideredirect(1)
# # useful for something like a splash screen

root.mainloop()

There is also the possibility that, for a Toplevel window other than the root one, you can do:

toplevel.transient(1)

and this will remove the min/max buttons, but it also depends on the window manager. From what I read, the MS Windows WM does remove them.

tzot
  • 92,761
  • 29
  • 141
  • 204
  • 2
    Thanks. I ended up using the overrideredirect - approach and added a ridge to the the bottom frame. Looks decent enough. – Vidar Jun 05 '10 at 11:11
  • 1
    root.resizable(0,0) worked for me in Ubuntu, 'm using tkinter – RahulArackal Mar 21 '14 at 06:12
  • 1
    @tzot root.overrideredirect(1) would hide the outer frame altogether. There will be no options for close, min or max. If a code containing this line was executed, then the window will stuck to the screen forever unless the IDLE is restarded or the OS is switched off. – Mohammed Jan 09 '15 at 20:03
  • 11
    root.attributes(toolwindow=1) This command does not work in Windows. The correct command is root.attributes("-toolwindow",1). Thanks! – Mohammed Jan 09 '15 at 20:08
  • For anyone, who seeks more flexible windows solution, [this](https://stackoverflow.com/a/47867275/6634373) might be useful! – CommonSense Dec 18 '17 at 13:15
  • FYI, toplevel.transient(root) works on Ubuntu 22.04 with Python 3.10.6 – Jack Griffin Jan 17 '23 at 04:31
14
from tkinter import  *

qw=Tk()
qw.resizable(0,0)      #will disable max/min tab of window
qw.mainloop()

enter image description here

from tkinter import  *

qw=Tk()
qw.overrideredirect(1) # will remove the top badge of window
qw.mainloop()

enter image description here

here are the two ways to disable maximize and minimize option in tkinter

remember the code for button shown in image is not in example as this is solution regarding how to make max/min tab nonfunctional or how to remove

Er M S Dandyan
  • 364
  • 3
  • 3
13

Windows

For windows, you can use -toolwindow attribute like that:

root.attributes('-toolwindow', True)

So if you want complete code, it's that

from tkinter import *

from tkinter import ttk

root = Tk()

root.attributes('-toolwindow', True)

root.mainloop()

Other window.attributes attributes:

-alpha
-transparentcolor
-disabled
-fullscreen
-toolwindow
-topmost

Important note this is only working with Windows. Not MacOS

Mac

With mac you can use overredirect attribute and a "x" button to close the window and this will do the job. :D like that:

from tkinter import *

from tkinter import ttk

window = Tk()

window.overredirect(True)

Button(window, text="x", command=window.destroy).pack()

window.mainloop()

Inspired by https://www.delftstack.com/howto/python-tkinter/how-to-create-full-screen-window-in-tkinter/

For me, it's working, i have a windows 7.

Comment me if i have a error.

Ellicode
  • 131
  • 1
  • 5
2

I merged answers from @demyaN and the others, and the following is a way to get the job done.

import ctypes as ct 
from tkinter import *

def setWinStyle(root):
    set_window_pos = ct.windll.user32.SetWindowPos
    set_window_long = ct.windll.user32.SetWindowLongPtrW
    get_window_long = ct.windll.user32.GetWindowLongPtrW
    get_parent = ct.windll.user32.GetParent

    # Identifiers
    gwl_style = -16

    ws_minimizebox = 131072
    ws_maximizebox = 65536

    swp_nozorder = 4
    swp_nomove = 2
    swp_nosize = 1
    swp_framechanged = 32

    hwnd = get_parent(root.winfo_id())

    old_style = get_window_long(hwnd, gwl_style) # Get the style

    new_style = old_style & ~ ws_maximizebox & ~ ws_minimizebox # New style, without max/min buttons

    set_window_long(hwnd, gwl_style, new_style) # Apply the new style

    set_window_pos(hwnd, 0, 0, 0, 0, 0, swp_nomove | swp_nosize | swp_nozorder | swp_framechanged)     # Updates

window = Tk()
Button(window, text="button").pack() # add your widgets here.
window.after(10, lambda: setWinStyle(window)) #call to change style after the mainloop started. Directly call setWinStyle will not work.
window.mainloop()

By the way, using window.attributes('-toolwindow', True) will remove the minimize and maximize boxes, but it will make the app not display in the taskbar, which is a problem for me.

rml
  • 803
  • 10
  • 14
  • Check [\[SO\]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer)](https://stackoverflow.com/a/58611011/4788546) for a common pitfall when working with *CTypes* (calling functions). *Tk* seem to disable buttons instead of hiding them. – CristiFati Mar 20 '23 at 21:04
0

Removing minimize/maximize buttons using ctypes

    import ctypes as ct

    set_window_pos = ct.windll.user32.SetWindowPos
    set_window_long = ct.windll.user32.SetWindowLongPtrW
    get_window_long = ct.windll.user32.GetWindowLongPtrW
    get_parent = ct.windll.user32.GetParent

    # Identifiers
    gwl_style = -16

    ws_minimizebox = 131072
    ws_maximizebox = 65536

    swp_nozorder = 4
    swp_nomove = 2
    swp_nosize = 1
    swp_framechanged = 32

    hwnd = get_parent(settings_panel.winfo_id())
    # Get the style
    old_style = get_window_long(hwnd, gwl_style)
    # New style, without max/min buttons
    new_style = old_style & ~ ws_maximizebox & ~ ws_minimizebox
    # Apply the new style
    set_window_long(hwnd, gwl_style, new_style)
    # Updates
    set_window_pos(hwnd, 0, 0, 0, 0, 0, swp_nomove | swp_nosize | swp_nozorder | swp_framechanged)
demyaN
  • 39
  • 1
  • 6
  • 4
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-ask). – Community Sep 15 '21 at 05:45
  • Doesn't work... – Jomme Dec 22 '22 at 16:33
  • Check [\[SO\]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer)](https://stackoverflow.com/a/58611011/4788546) for a common pitfall when working with *CTypes* (calling functions). *Tk* seem to disable buttons instead of hiding them. – CristiFati Mar 20 '23 at 21:06