7

I often see Tkinter applications initialize Menu widgets using tearoff=0 in the constructor.

import tkinter as tk

root = tk.Tk()
menubar = tk.Menu(root)    
filemenu = tk.Menu(menubar, tearoff=0)

effbot.org's documentation for Menu specifies that the default value for tearoff is 1, but it doesn't explain what the value is used for.

tearoff=
    Default value is 1. (tearOff/TearOff)
tearoffcommand=
    No default value. (tearOffCommand/TearOffCommand)

What does the tearoff attribute do when initializing a tkinter Menu widget?

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
  • A tear-off menu can be dragged away from the position where it popped up, and left open permanently. It's a UI element that has fallen out of favor; I'm not sure that all platforms that Tkinter runs on even support it. – jasonharper Mar 26 '18 at 18:45

4 Answers4

11

The official python docs admit that they're a little light on details:

The tkinter package is a thin object-oriented layer on top of Tcl/Tk. To use tkinter, you don’t need to write Tcl code, but you will need to consult the Tk documentation, and occasionally the Tcl documentation.

The Tk documentation for tearoff gives you what you're looking for:

tearoff allows you to detach menus for the main window creating floating menus. If you create a menu you will see dotted lines at the top when you click a top menu item. If you click those dotted lines the menu tears off and becomes floating.

Darrick Herwehe
  • 3,553
  • 1
  • 21
  • 30
6

Tkinter menu with tearoffHere you can see a tkinter Menu tear-off with the code for it in the background. I'm not sure how useful this is going to be but according to New Mexico Tech:

Normally, a menu can be torn off: the first position (position 0) in the list of choices is occupied by the tear-off element, and the additional choices are added starting at position 1. If you set tearoff=0, the menu will not have a tear-off feature, and choices will be added starting at position 0.

Minion Jim
  • 1,239
  • 13
  • 30
  • Usefulness depends on how the developer structures the menus. Sometimes it is easier to just have the menus on the side that you can click on instead of having to drop down to select. – cup Sep 30 '21 at 11:29
0

Try this if you want to test the floating menu if you are using Windows.

from tkinter import *
import re

class HoverInfo(Menu):
    def __init__(self, parent, text, command=None):
       self._com = command
       Menu.__init__(self,parent, tearoff=1)
       if not isinstance(text, str):
          raise TypeError('Trying to initialise a Hover Menu with a non string type: ' + text.__class__.__name__)
       toktext=re.split('\n', text)
       for t in toktext:
          self.add_command(label = t)
          self._displayed=False
          self.master.bind("<Enter>",self.Display )
          self.master.bind("<Leave>",self.Remove )

    def __del__(self):
       self.master.unbind("<Enter>")
       self.master.unbind("<Leave>")

    def Display(self,event):
       if not self._displayed:
          self._displayed=True
          self.post(event.x_root, event.y_root)
       if self._com != None:
          self.master.unbind_all("<Return>")
          self.master.bind_all("<Return>", self.Click)

    def Remove(self, event):
     if self._displayed:
       self._displayed=False
       self.unpost()
     if self._com != None:
       self.unbind_all("<Return>")

    def Click(self, event):
       self._com()

class MyApp(Frame):
   def __init__(self, parent=None):
      Frame.__init__(self, parent)
      self.grid()
      self.lbl = Label(self, text='testing')
      self.lbl.grid()

      self.hover = HoverInfo(self, 'while hovering press return \n for an exciting msg', self.HelloWorld)

   def HelloWorld(self):
      print('Hello World')

app = MyApp()
app.master.title('test')
app.mainloop()

This example is Hover Class by Gogo. Display message when hovering over something with mouse cursor in Python

I Just set tear-off to 1 to see the floating effect.

Raj Mehta
  • 314
  • 1
  • 4
  • 20
0

By default, the choices in the menu start taking place from position 1. If we set the tearoff = 1, then it will start taking place from 0th position