¿Cómo puedo mostrar puntas de herramientas en Tkinter?

Las puntas de la herramienta son esos pequeños pedazos de texto que aparecen cuando el ratón pasa sobre un widget durante cierto tiempo.

¿Cómo puedo añadir un mensaje de herramienta a mi tkinter ¿Aplicación de pitón?

Example of tooltip

Pregunta hecha hace 13 años, 7 meses, 19 días - Por scriptsculptor52b5


11 Respuestas:

  • He probado el código en el blog mencionado por ars, y también probó el código del IDLE lib.

    Mientras ambos trabajaban, no me gustó cómo la punta de la herramienta del IDLE era limitada en tamaño (tenía que introducir manualmente nuevas líneas como listas separadas) , y cómo los consejos aparecieron inmediatamente en el formulario de código del blog.

    Hice un híbrido entre los dos. Le permite especificar una longitud de la envoltura y el tiempo de la envoltura, sin ninguna restricción en cada:

    """ tk_ToolTip_class101.py
    gives a Tkinter widget a tooltip as the mouse is above the widget
    tested with Python27 and Python34  by  vegaseat  09sep2014
    www.daniweb.com/programming/software-development/code/484591/a-tooltip-class-for-tkinter
    
    Modified to include a delay time by Victor Zaccardo, 25mar16
    """
    
    try:
        # for Python2
        import Tkinter as tk
    except ImportError:
        # for Python3
        import tkinter as tk
    
    class CreateToolTip(object):
        """
        create a tooltip for a given widget
        """
        def __init__(self, widget, text='widget info'):
            self.waittime = 500     #miliseconds
            self.wraplength = 180   #pixels
            self.widget = widget
            self.text = text
            self.widget.bind("", self.enter)
            self.widget.bind("", self.leave)
            self.widget.bind("", self.leave)
            self.id = None
            self.tw = None
    
        def enter(self, event=None):
            self.schedule()
    
        def leave(self, event=None):
            self.unschedule()
            self.hidetip()
    
        def schedule(self):
            self.unschedule()
            self.id = self.widget.after(self.waittime, self.showtip)
    
        def unschedule(self):
            id = self.id
            self.id = None
            if id:
                self.widget.after_cancel(id)
    
        def showtip(self, event=None):
            x = y = 0
            x, y, cx, cy = self.widget.bbox("insert")
            x += self.widget.winfo_rootx() + 25
            y += self.widget.winfo_rooty() + 20
            # creates a toplevel window
            self.tw = tk.Toplevel(self.widget)
            # Leaves only the label and removes the app window
            self.tw.wm_overrideredirect(True)
            self.tw.wm_geometry("+%d+%d" % (x, y))
            label = tk.Label(self.tw, text=self.text, justify='left',
                           background="#ffffff", relief='solid', borderwidth=1,
                           wraplength = self.wraplength)
            label.pack(ipadx=1)
    
        def hidetip(self):
            tw = self.tw
            self.tw= None
            if tw:
                tw.destroy()
    
    # testing ...
    if __name__ == '__main__':
        root = tk.Tk()
        btn1 = tk.Button(root, text="button 1")
        btn1.pack(padx=10, pady=5)
        button1_ttp = CreateToolTip(btn1, \
       'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, '
       'consectetur, adipisci velit. Neque porro quisquam est qui dolorem ipsum '
       'quia dolor sit amet, consectetur, adipisci velit. Neque porro quisquam '
       'est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.')
    
        btn2 = tk.Button(root, text="button 2")
        btn2.pack(padx=10, pady=5)
        button2_ttp = CreateToolTip(btn2, \
        "First thing's first, I'm the realest. Drop this and let the whole world "
        "feel it. And I'm still in the Murda Bizness. I could hold you down, like "
        "I'm givin' lessons in  physics. You should want a bad Vic like this.")
        root.mainloop()
    

    Captura de Pantalla

    Example of hovertext

    Respondida el Jul 11, 2010 a las 05:28 - por pixelpioneer

    Votos positivos: 0 | Votos negativos: 0

  • Una solución simple en Python 3.7+

    Picture

    import tkinter as tk
    from idlelib.tooltip import Hovertip
        
    app = tk.Tk()
    myBtn = tk.Button(app,text='?')
    myBtn.pack(pady=30)
    myTip = Hovertip(myBtn,'This is \na multiline tooltip.')
    app.mainloop()
    

    Respondida el Jul 11, 2010 a las 05:37 - por codecrusader

    Votos positivos: 0 | Votos negativos: 0

  • El Pmw.Balloon de la clase Pmw toolkit para Tkinter dibujará consejos de herramientas.

    También echa un vistazo a esto blog, que adapta algún código de IDLE utilizado para mostrar consejos de herramientas con Tkinter.

    Respondida el Jul 11, 2010 a las 05:43 - por compilerchieftain

    Votos positivos: 0 | Votos negativos: 0

  • En primer lugar, me gusta mucho. Punta de herramientas de Alberto Vassena e intenté comentar su post con esta corrección de fallos, pero como nuevo usuario no tengo suficientes puntos para hacer un comentario, así que estoy haciendo una respuesta. Espero que esto sea aceptable.

    Había un error muy pequeño en La excelente respuesta de Alberto Vassena y mejorado ToolTip.

    Error: Para la etiqueta actual su código llama ttk. Label en lugar de Tk. Label Esto dio como resultado la caja de herramientas que se está renderizando pero no el texto actual hasta un evento UI adicional, como otro movimiento del ratón o un evento del teclado.

    Aquí está el código corregido para una copia completa " pasta:

    import tkinter as tk
    import tkinter.ttk as ttk
    
    
    class Tooltip:
        '''
        It creates a tooltip for a given widget as the mouse goes on it.
    
        see:
    
        http://stackoverflow.com/questions/3221956/
               what-is-the-simplest-way-to-make-tooltips-
               in-tkinter/36221216#36221216
    
        http://www.daniweb.com/programming/software-development/
               code/484591/a-tooltip-class-for-tkinter
    
        - Originally written by vegaseat on 2014.09.09.
    
        - Modified to include a delay time by Victor Zaccardo on 2016.03.25.
    
        - Modified
            - to correct extreme right and extreme bottom behavior,
            - to stay inside the screen whenever the tooltip might go out on
              the top but still the screen is higher than the tooltip,
            - to use the more flexible mouse positioning,
            - to add customizable background color, padding, waittime and
              wraplength on creation
          by Alberto Vassena on 2016.11.05.
    
          Tested on Ubuntu 16.04/16.10, running Python 3.5.2
    
        TODO: themes styles support
        '''
    
        def __init__(self, widget,
                     *,
                     bg='#FFFFEA',
                     pad=(5, 3, 5, 3),
                     text='widget info',
                     waittime=400,
                     wraplength=250):
    
            self.waittime = waittime  # in miliseconds, originally 500
            self.wraplength = wraplength  # in pixels, originally 180
            self.widget = widget
            self.text = text
            self.widget.bind("", self.onEnter)
            self.widget.bind("", self.onLeave)
            self.widget.bind("", self.onLeave)
            self.bg = bg
            self.pad = pad
            self.id = None
            self.tw = None
    
        def onEnter(self, event=None):
            self.schedule()
    
        def onLeave(self, event=None):
            self.unschedule()
            self.hide()
    
        def schedule(self):
            self.unschedule()
            self.id = self.widget.after(self.waittime, self.show)
    
        def unschedule(self):
            id_ = self.id
            self.id = None
            if id_:
                self.widget.after_cancel(id_)
    
        def show(self):
            def tip_pos_calculator(widget, label,
                                   *,
                                   tip_delta=(10, 5), pad=(5, 3, 5, 3)):
    
                w = widget
    
                s_width, s_height = w.winfo_screenwidth(), w.winfo_screenheight()
    
                width, height = (pad[0] + label.winfo_reqwidth() + pad[2],
                                 pad[1] + label.winfo_reqheight() + pad[3])
    
                mouse_x, mouse_y = w.winfo_pointerxy()
    
                x1, y1 = mouse_x + tip_delta[0], mouse_y + tip_delta[1]
                x2, y2 = x1 + width, y1 + height
    
                x_delta = x2 - s_width
                if x_delta < 0:
                    x_delta = 0
                y_delta = y2 - s_height
                if y_delta < 0:
                    y_delta = 0
    
                offscreen = (x_delta, y_delta) != (0, 0)
    
                if offscreen:
    
                    if x_delta:
                        x1 = mouse_x - tip_delta[0] - width
    
                    if y_delta:
                        y1 = mouse_y - tip_delta[1] - height
    
                offscreen_again = y1 < 0  # out on the top
    
                if offscreen_again:
                    # No further checks will be done.
    
                    # TIP:
                    # A further mod might automagically augment the
                    # wraplength when the tooltip is too high to be
                    # kept inside the screen.
                    y1 = 0
    
                return x1, y1
    
            bg = self.bg
            pad = self.pad
            widget = self.widget
    
            # creates a toplevel window
            self.tw = tk.Toplevel(widget)
    
            # Leaves only the label and removes the app window
            self.tw.wm_overrideredirect(True)
    
            win = tk.Frame(self.tw,
                           background=bg,
                           borderwidth=0)
            label = tk.Label(win,
                              text=self.text,
                              justify=tk.LEFT,
                              background=bg,
                              relief=tk.SOLID,
                              borderwidth=0,
                              wraplength=self.wraplength)
    
            label.grid(padx=(pad[0], pad[2]),
                       pady=(pad[1], pad[3]),
                       sticky=tk.NSEW)
            win.grid()
    
            x, y = tip_pos_calculator(widget, label)
    
            self.tw.wm_geometry("+%d+%d" % (x, y))
    
        def hide(self):
            tw = self.tw
            if tw:
                tw.destroy()
            self.tw = None
    
    
    if __name__ == '__main__':
    
        import random
    
        def further_text():
            # texts generated at http://lorem-ipsum.perbang.dk/
            short_text = ('Lorem ipsum dolor sit amet, mauris tellus, '
                         'porttitor torquent eu. Magna aliquet lorem, '
                         'cursus sit ac, in in. Dolor aliquet, cum integer. '
                         'Proin aliquet, porttitor pulvinar mauris. Tellus '
                         'lectus, amet cras, neque lacus quis. Malesuada '
                         'nibh. Eleifend nam, in eget a. Nec turpis, erat '
                         'wisi semper')
            medium_text = ('Lorem ipsum dolor sit amet, suspendisse aenean '
                           'ipsum sollicitudin, pellentesque nunc ultrices ac '
                           'ut, arcu elit turpis senectus convallis. Ac orci '
                           'pretium sed gravida, tortor nulla felis '
                           'consectetuer, mauris egestas est erat. Ut enim '
                           'tellus at diam, ac sagittis vel proin. Massa '
                           'eleifend orci tortor sociis, scelerisque in pede '
                           'metus phasellus, est tempor gravida nam, ante '
                           'fusce sem tempor. Mi diam auctor vel pede, mus '
                           'non mi luctus luctus, lectus sit varius repellat '
                           'eu')
            long_text = ('Lorem ipsum dolor sit amet, velit eu nam cursus '
                         'quisque gravida sollicitudin, felis arcu interdum '
                         'error quam quis massa, et velit libero ligula est '
                         'donec. Suspendisse fringilla urna ridiculus dui '
                         'volutpat justo, quisque nisl eget sed blandit '
                         'egestas, libero nullam magna sem dui nam, auctor '
                         'vehicula nunc arcu vel sed dictum, tincidunt vitae '
                         'id tristique aptent platea. Lacus eros nec proin '
                         'morbi sollicitudin integer, montes suspendisse '
                         'augue lorem iaculis sed, viverra sed interdum eget '
                         'ut at pulvinar, turpis vivamus ac pharetra nulla '
                         'maecenas ut. Consequat dui condimentum lectus nulla '
                         'vitae, nam consequat fusce ac facilisis eget orci, '
                         'cras enim donec aenean sed dolor aliquam, elit '
                         'lorem in a nec fringilla, malesuada curabitur diam '
                         'nonummy nisl nibh ipsum. In odio nunc nec porttitor '
                         'ipsum, nunc ridiculus platea wisi turpis praesent '
                         'vestibulum, suspendisse hendrerit amet quis vivamus '
                         'adipiscing elit, ut dolor nec nonummy mauris nec '
                         'libero, ad rutrum id tristique facilisis sed '
                         'ultrices. Convallis velit posuere mauris lectus sit '
                         'turpis, lobortis volutpat et placerat leo '
                         'malesuada, vulputate id maecenas at a volutpat '
                         'vulputate, est augue nec proin ipsum pellentesque '
                         'fringilla. Mattis feugiat metus ultricies repellat '
                         'dictum, suspendisse erat rhoncus ultricies in ipsum, '
                         'nulla ante pellentesque blandit ligula sagittis '
                         'ultricies, sed tortor sodales pede et duis platea')
    
            text = random.choice([short_text, medium_text, long_text, long_text])
    
            return '\nFurther info: ' + text
    
        def main_01(wraplength=200):
    
            # alias
            stuff = further_text
    
            root = tk.Tk()
            frame = ttk.Frame(root)
    
            btn_ne = ttk.Button(frame, text='North East')
            btn_se = ttk.Button(frame, text='South East')
            btn_sw = ttk.Button(frame, text='South West')
            btn_nw = ttk.Button(frame, text='North West')
            btn_center = ttk.Button(frame, text='Center')
            btn_n = ttk.Button(frame, text='North')
            btn_e = ttk.Button(frame, text='East')
            btn_s = ttk.Button(frame, text='South')
            btn_w = ttk.Button(frame, text='West')
    
            Tooltip(btn_nw, text='North West' + stuff(), wraplength=wraplength)
            Tooltip(btn_ne, text='North East' + stuff(), wraplength=wraplength)
            Tooltip(btn_se, text='South East' + stuff(), wraplength=wraplength)
            Tooltip(btn_sw, text='South West' + stuff(), wraplength=wraplength)
            Tooltip(btn_center, text='Center' + stuff(), wraplength=wraplength)
            Tooltip(btn_n, text='North' + stuff(), wraplength=wraplength)
            Tooltip(btn_e, text='East' + stuff(), wraplength=wraplength)
            Tooltip(btn_s, text='South' + stuff(), wraplength=wraplength)
            Tooltip(btn_w, text='West' + stuff(), wraplength=wraplength)
    
            r = 0
            c = 0
            pad = 10
            btn_nw.grid(row=r, column=c, padx=pad, pady=pad, sticky=tk.NW)
            btn_n.grid(row=r, column=c + 1, padx=pad, pady=pad, sticky=tk.N)
            btn_ne.grid(row=r, column=c + 2, padx=pad, pady=pad, sticky=tk.NE)
    
            r += 1
            btn_w.grid(row=r, column=c + 0, padx=pad, pady=pad, sticky=tk.W)
            btn_center.grid(row=r, column=c + 1, padx=pad, pady=pad,
                        sticky=tk.NSEW)
            btn_e.grid(row=r, column=c + 2, padx=pad, pady=pad, sticky=tk.E)
    
            r += 1
            btn_sw.grid(row=r, column=c, padx=pad, pady=pad, sticky=tk.SW)
            btn_s.grid(row=r, column=c + 1, padx=pad, pady=pad, sticky=tk.S)
            btn_se.grid(row=r, column=c + 2, padx=pad, pady=pad, sticky=tk.SE)
    
            frame.grid(sticky=tk.NSEW)
            for i in (0, 2):
                frame.rowconfigure(i, weight=1)
                frame.columnconfigure(i, weight=1)
    
            root.rowconfigure(0, weight=1)
            root.columnconfigure(0, weight=1)
    
            root.title('Tooltip wraplength = {}'.format(wraplength))
            root.mainloop()
    
        def main():
            print('Trying out three different wraplengths:')
            for i, wl in enumerate((200, 250, 400), 1):
                print(' ', i)
                main_01(wl)
            print('Done.')
    
        main()
    

    Respondida el Jul 11, 2010 a las 05:53 - por htmlhero

    Votos positivos: 0 | Votos negativos: 0

  • No recomendaría usar Tix widgets, desde Tix básicamente ya no es compatible y generalmente causa muchos problemas.

    Lo siguiente es un ejemplo de una herramienta tomada directamente del Pitón idlelib Módulo:

    # general purpose 'tooltip' routines - currently unused in idlefork
    # (although the 'calltips' extension is partly based on this code)
    # may be useful for some purposes in (or almost in ;) the current project scope
    # Ideas gleaned from PySol
    
    from tkinter import *
    
    
    class ToolTipBase:
    
        def __init__(self, button):
            self.button = button
            self.tipwindow = None
            self.id = None
            self.x = self.y = 0
            self._id1 = self.button.bind("", self.enter)
            self._id2 = self.button.bind("", self.leave)
            self._id3 = self.button.bind("", self.leave)
    
        def enter(self, event=None):
            self.schedule()
    
        def leave(self, event=None):
            self.unschedule()
            self.hidetip()
    
        def schedule(self):
            self.unschedule()
            self.id = self.button.after(1500, self.showtip)
    
        def unschedule(self):
            id = self.id
            self.id = None
            if id:
                self.button.after_cancel(id)
    
        def showtip(self):
            if self.tipwindow:
                return
            # The tip window must be completely outside the button;
            # otherwise when the mouse enters the tip window we get
            # a leave event and it disappears, and then we get an enter
            # event and it reappears, and so on forever :-(
            x = self.button.winfo_rootx() + 20
            y = self.button.winfo_rooty() + self.button.winfo_height() + 1
            self.tipwindow = tw = Toplevel(self.button)
            tw.wm_overrideredirect(1)
            tw.wm_geometry("+%d+%d" % (x, y))
            self.showcontents()
    
        def showcontents(self, text="Your text here"):
            # Override this in derived class
            label = Label(self.tipwindow, text=text, justify=LEFT,
                          background="#ffffe0", relief=SOLID, borderwidth=1)
            label.pack()
    
        def hidetip(self):
            tw = self.tipwindow
            self.tipwindow = None
            if tw:
                tw.destroy()
    
    
    class ToolTip(ToolTipBase):
    
        def __init__(self, button, text):
            ToolTipBase.__init__(self, button)
            self.text = text
    
        def showcontents(self):
            ToolTipBase.showcontents(self, self.text)
    
    
    class ListboxToolTip(ToolTipBase):
    
        def __init__(self, button, items):
            ToolTipBase.__init__(self, button)
            self.items = items
    
        def showcontents(self):
            listbox = Listbox(self.tipwindow, background="#ffffe0")
            listbox.pack()
            for item in self.items:
                listbox.insert(END, item)
    

    También podría importar el módulo directamente y utilizarlo:

    from idlelib.tooltip import * ##corrected wrong import
    
    def main():
        root = Tk()
        b = Button(root, text="Hello", command=root.destroy)
        b.pack()
        root.update()
        tip = ListboxToolTip(b, ["Hello", "world"])
        root.mainloop()
    
    if __name__ == '__main__':
        main()
    

    Estoy usando Python 3.4, y es posible que las distribuciones de otros Python no contengan esto ToolTip módulo.

    Respondida el Jul 11, 2010 a las 06:00 - por scriptsculptor52b5

    Votos positivos: 0 | Votos negativos: 0

  • Ya que utiliza Windows 7, su instalación Python probablemente ya incluye Tix. Usa el widget Tix.Balloon. Código de muestra existe en el árbol fuente Python.

    Básicamente, creas un Tix.Balloon widget, lo atas a otros widgets a través de sus .bind_widget método y proporcionar el mensaje de globo utilizando su balloonmsg argumento.

    Respondida el Jul 11, 2010 a las 06:06 - por bugbusterx

    Votos positivos: 0 | Votos negativos: 0

  • He modificado el Herramienta clase crxguy52 ha sugerido. La clase que sigue ahora debe trabajar en casi cualquier caso, donde sea necesario para instantánearlo: NW, N, NE, E, SE, S, SW, W.

    El único caso que mi clase no maneja actualmente es el en el que la punta de la herramienta es simplemente más alta que toda la pantalla (probablemente muy rara, pero simplemente ensancharla pasando manualmente un mayor envoltorio puede resolver inmediatamente ese caso también).

    import tkinter as tk
    import tkinter.ttk as ttk
    
    
    class Tooltip:
        '''
        It creates a tooltip for a given widget as the mouse goes on it.
    
        see:
    
        https://stackoverflow.com/questions/3221956/
               what-is-the-simplest-way-to-make-tooltips-
               in-tkinter/36221216#36221216
    
        http://www.daniweb.com/programming/software-development/
               code/484591/a-tooltip-class-for-tkinter
    
        - Originally written by vegaseat on 2014.09.09.
    
        - Modified to include a delay time by Victor Zaccardo on 2016.03.25.
    
        - Modified
            - to correct extreme right and extreme bottom behavior,
            - to stay inside the screen whenever the tooltip might go out on 
              the top but still the screen is higher than the tooltip,
            - to use the more flexible mouse positioning,
            - to add customizable background color, padding, waittime and
              wraplength on creation
          by Alberto Vassena on 2016.11.05.
    
          Tested on Ubuntu 16.04/16.10, running Python 3.5.2
    
        TODO: themes styles support
        '''
    
        def __init__(self, widget,
                     *,
                     bg='#FFFFEA',
                     pad=(5, 3, 5, 3),
                     text='widget info',
                     waittime=400,
                     wraplength=250):
    
            self.waittime = waittime  # in miliseconds, originally 500
            self.wraplength = wraplength  # in pixels, originally 180
            self.widget = widget
            self.text = text
            self.widget.bind("", self.onEnter)
            self.widget.bind("", self.onLeave)
            self.widget.bind("", self.onLeave)
            self.bg = bg
            self.pad = pad
            self.id = None
            self.tw = None
    
        def onEnter(self, event=None):
            self.schedule()
    
        def onLeave(self, event=None):
            self.unschedule()
            self.hide()
    
        def schedule(self):
            self.unschedule()
            self.id = self.widget.after(self.waittime, self.show)
    
        def unschedule(self):
            id_ = self.id
            self.id = None
            if id_:
                self.widget.after_cancel(id_)
    
        def show(self):
            def tip_pos_calculator(widget, label,
                                   *,
                                   tip_delta=(10, 5), pad=(5, 3, 5, 3)):
    
                w = widget
    
                s_width, s_height = w.winfo_screenwidth(), w.winfo_screenheight()
    
                width, height = (pad[0] + label.winfo_reqwidth() + pad[2],
                                 pad[1] + label.winfo_reqheight() + pad[3])
    
                mouse_x, mouse_y = w.winfo_pointerxy()
    
                x1, y1 = mouse_x + tip_delta[0], mouse_y + tip_delta[1]
                x2, y2 = x1 + width, y1 + height
    
                x_delta = x2 - s_width
                if x_delta < 0:
                    x_delta = 0
                y_delta = y2 - s_height
                if y_delta < 0:
                    y_delta = 0
    
                offscreen = (x_delta, y_delta) != (0, 0)
    
                if offscreen:
    
                    if x_delta:
                        x1 = mouse_x - tip_delta[0] - width
    
                    if y_delta:
                        y1 = mouse_y - tip_delta[1] - height
    
                offscreen_again = y1 < 0  # out on the top
    
                if offscreen_again:
                    # No further checks will be done.
    
                    # TIP:
                    # A further mod might automagically augment the
                    # wraplength when the tooltip is too high to be
                    # kept inside the screen.
                    y1 = 0
    
                return x1, y1
    
            bg = self.bg
            pad = self.pad
            widget = self.widget
    
            # creates a toplevel window
            self.tw = tk.Toplevel(widget)
    
            # Leaves only the label and removes the app window
            self.tw.wm_overrideredirect(True)
    
            win = tk.Frame(self.tw,
                           background=bg,
                           borderwidth=0)
            label = ttk.Label(win,
                              text=self.text,
                              justify=tk.LEFT,
                              background=bg,
                              relief=tk.SOLID,
                              borderwidth=0,
                              wraplength=self.wraplength)
    
            label.grid(padx=(pad[0], pad[2]),
                       pady=(pad[1], pad[3]),
                       sticky=tk.NSEW)
            win.grid()
    
            x, y = tip_pos_calculator(widget, label)
    
            self.tw.wm_geometry("+%d+%d" % (x, y))
    
        def hide(self):
            tw = self.tw
            if tw:
                tw.destroy()
            self.tw = None
    
    
    if __name__ == '__main__':
    
        import random
    
        def further_text():
            # texts generated at http://lorem-ipsum.perbang.dk/
            short_text = ('Lorem ipsum dolor sit amet, mauris tellus, '
                         'porttitor torquent eu. Magna aliquet lorem, '
                         'cursus sit ac, in in. Dolor aliquet, cum integer. '
                         'Proin aliquet, porttitor pulvinar mauris. Tellus '
                         'lectus, amet cras, neque lacus quis. Malesuada '
                         'nibh. Eleifend nam, in eget a. Nec turpis, erat '
                         'wisi semper')
            medium_text = ('Lorem ipsum dolor sit amet, suspendisse aenean '
                           'ipsum sollicitudin, pellentesque nunc ultrices ac '
                           'ut, arcu elit turpis senectus convallis. Ac orci '
                           'pretium sed gravida, tortor nulla felis '
                           'consectetuer, mauris egestas est erat. Ut enim '
                           'tellus at diam, ac sagittis vel proin. Massa '
                           'eleifend orci tortor sociis, scelerisque in pede '
                           'metus phasellus, est tempor gravida nam, ante '
                           'fusce sem tempor. Mi diam auctor vel pede, mus '
                           'non mi luctus luctus, lectus sit varius repellat '
                           'eu')
            long_text = ('Lorem ipsum dolor sit amet, velit eu nam cursus '
                         'quisque gravida sollicitudin, felis arcu interdum '
                         'error quam quis massa, et velit libero ligula est '
                         'donec. Suspendisse fringilla urna ridiculus dui '
                         'volutpat justo, quisque nisl eget sed blandit '
                         'egestas, libero nullam magna sem dui nam, auctor '
                         'vehicula nunc arcu vel sed dictum, tincidunt vitae '
                         'id tristique aptent platea. Lacus eros nec proin '
                         'morbi sollicitudin integer, montes suspendisse '
                         'augue lorem iaculis sed, viverra sed interdum eget '
                         'ut at pulvinar, turpis vivamus ac pharetra nulla '
                         'maecenas ut. Consequat dui condimentum lectus nulla '
                         'vitae, nam consequat fusce ac facilisis eget orci, '
                         'cras enim donec aenean sed dolor aliquam, elit '
                         'lorem in a nec fringilla, malesuada curabitur diam '
                         'nonummy nisl nibh ipsum. In odio nunc nec porttitor '
                         'ipsum, nunc ridiculus platea wisi turpis praesent '
                         'vestibulum, suspendisse hendrerit amet quis vivamus '
                         'adipiscing elit, ut dolor nec nonummy mauris nec '
                         'libero, ad rutrum id tristique facilisis sed '
                         'ultrices. Convallis velit posuere mauris lectus sit '
                         'turpis, lobortis volutpat et placerat leo '
                         'malesuada, vulputate id maecenas at a volutpat '
                         'vulputate, est augue nec proin ipsum pellentesque '
                         'fringilla. Mattis feugiat metus ultricies repellat '
                         'dictum, suspendisse erat rhoncus ultricies in ipsum, '
                         'nulla ante pellentesque blandit ligula sagittis '
                         'ultricies, sed tortor sodales pede et duis platea')
    
            text = random.choice([short_text, medium_text, long_text, long_text])
    
            return '\nFurther info: ' + text
    
        def main_01(wraplength=200):
    
            # alias
            stuff = further_text
    
            root = tk.Tk()
            frame = ttk.Frame(root)
    
            btn_ne = ttk.Button(frame, text='North East')
            btn_se = ttk.Button(frame, text='South East')
            btn_sw = ttk.Button(frame, text='South West')
            btn_nw = ttk.Button(frame, text='North West')
            btn_center = ttk.Button(frame, text='Center')
            btn_n = ttk.Button(frame, text='North')
            btn_e = ttk.Button(frame, text='East')
            btn_s = ttk.Button(frame, text='South')
            btn_w = ttk.Button(frame, text='West')
    
            Tooltip(btn_nw, text='North West' + stuff(), wraplength=wraplength)
            Tooltip(btn_ne, text='North East' + stuff(), wraplength=wraplength)
            Tooltip(btn_se, text='South East' + stuff(), wraplength=wraplength)
            Tooltip(btn_sw, text='South West' + stuff(), wraplength=wraplength)
            Tooltip(btn_center, text='Center' + stuff(), wraplength=wraplength)
            Tooltip(btn_n, text='North' + stuff(), wraplength=wraplength)
            Tooltip(btn_e, text='East' + stuff(), wraplength=wraplength)
            Tooltip(btn_s, text='South' + stuff(), wraplength=wraplength)
            Tooltip(btn_w, text='West' + stuff(), wraplength=wraplength)
    
            r = 0
            c = 0
            pad = 10
            btn_nw.grid(row=r, column=c, padx=pad, pady=pad, sticky=tk.NW)
            btn_n.grid(row=r, column=c + 1, padx=pad, pady=pad, sticky=tk.N)
            btn_ne.grid(row=r, column=c + 2, padx=pad, pady=pad, sticky=tk.NE)
    
            r += 1
            btn_w.grid(row=r, column=c + 0, padx=pad, pady=pad, sticky=tk.W)
            btn_center.grid(row=r, column=c + 1, padx=pad, pady=pad,
                        sticky=tk.NSEW)
            btn_e.grid(row=r, column=c + 2, padx=pad, pady=pad, sticky=tk.E)
    
            r += 1
            btn_sw.grid(row=r, column=c, padx=pad, pady=pad, sticky=tk.SW)
            btn_s.grid(row=r, column=c + 1, padx=pad, pady=pad, sticky=tk.S)
            btn_se.grid(row=r, column=c + 2, padx=pad, pady=pad, sticky=tk.SE)
    
            frame.grid(sticky=tk.NSEW)
            for i in (0, 2):
                frame.rowconfigure(i, weight=1)
                frame.columnconfigure(i, weight=1)
    
            root.rowconfigure(0, weight=1)
            root.columnconfigure(0, weight=1)
    
            root.title('Tooltip wraplength = {}'.format(wraplength))
            root.mainloop()
    
        def main():
            print('Trying out three different wraplengths:')
            for i, wl in enumerate((200, 250, 400), 1):
                print(' ', i)
                main_01(wl)
            print('Done.')
    
        main()
    

    HTH. He publicado Aquí. a CanvasTooltip clase que permite atar puntas de herramientas a elementos creados dentro de un tkinter Canvas.

    Respondida el Jul 11, 2010 a las 06:13 - por quantumquasar

    Votos positivos: 0 | Votos negativos: 0

  • Aunque hay múltiples respuestas, añadiré mis 2 centavos.

    class ToolTip:
        def __init__(self,widget,text=None):
    
            def on_enter(event):
                self.tooltip=tk.Toplevel()
                self.tooltip.overrideredirect(True)
                self.tooltip.geometry(f'+{event.x_root+15}+{event.y_root+10}')
    
                self.label=tk.Label(self.tooltip,text=self.text)
                self.label.pack()
    
            def on_leave(event):
                self.tooltip.destroy()
    
            self.widget=widget
            self.text=text
    
            self.widget.bind('',on_enter)
            self.widget.bind('',on_leave)
    

    Esta es una herramienta básica que se mostrará en relación con la posición del cursor.

    Respondida el Jul 11, 2010 a las 06:21 - por scriptsculptorbf10

    Votos positivos: 0 | Votos negativos: 0

  • from tkinter import *
    from tkinter.tix import *
    root = Tk()
    btn1 = Button(root, text="hello")
    btn1.grid(row=0, column=0)
    balloon = Balloon(root, bg="white", title="Help")
    balloon.bind_widget(btn1, balloonmsg="Click to Exit")
    root.mainloop()
    

    Respondida el Jul 11, 2010 a las 06:26 - por codecrusader

    Votos positivos: 0 | Votos negativos: 0

  • Para agregar puntas de herramientas (tooltips) a los widgets de Tkinter en Python, puedes utilizar la siguiente función:

    python
    import tkinter as tk
    from tkinter import messagebox
    
    def show_tooltip(widget, message):
        def enter(event):
            messagebox.showinfo("Tooltip", message)
        def leave(event):
            messagebox.showinfo("Tooltip", "")
    
        widget.bind("", enter)
        widget.bind("", leave)
    
    

    Ejemplo de uso

    root = tk.Tk() button = tk.Button(root, text="Hover over me") button.pack() show_tooltip(button, "Soy un tooltip") root.mainloop()

    En este código, se define la función show_tooltip que recibe como parámetros el widget al que se le agregará la punta de herramientas y el mensaje que se mostrará. La función vincula los eventos <Enter> y <Leave> del widget con las funciones que muestran y ocultan la ventana emergente del mensaje.

    Es importante tener en cuenta que la función messagebox.showinfo se utiliza en este ejemplo para mostrar la punta de herramientas. Esto mostrará una ventana emergente con el mensaje del tooltip. Puedes personalizar esta lógica

    Respondida el Jul 12, 2010 a las 05:29 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Para mostrar información sobre herramientas en Tkinter, puedes utilizar la biblioteca ttk. Los pasos para agregar una información sobre herramientas a un widget son los siguientes:

    • Importar ttk: Importa el módulo `ttk` en tu script de Python.
    python
    import tkinter as tk
    import tkinter.ttk as ttk
    
    • Crear una instancia de la ventana: Crea una instancia de la ventana principal de Tkinter.
    python
    root = tk.Tk()
    
    • Crear un widget y adjuntar una información sobre herramientas: Crea el widget al que deseas adjuntar la información sobre herramientas y usa el método `setTooltip` para establecer el texto de la información sobre herramientas.
    python
    button = ttk.Button(root, text="Mi botón")
    button.setTooltip("Este es mi botón de ejemplo.")
    
    • Mainloop: Inicia el bucle principal de Tkinter para que la ventana permanezca abierta y responda a los eventos.
    python
    root.mainloop()
    

    Ejemplo:

    El siguiente código crea una ventana con dos botones, cada uno con su propia información sobre herramientas:

    python
    import tkinter as tk
    import tkinter.ttk as ttk
    
    root = tk.Tk()
    
    button1 = ttk.Button(root, text="Botón 1")
    button1.setTooltip("Esta es la información sobre herramientas del botón 1.")
    
    button2 = ttk.Button(root, text="Botón 2")
    button2.setTooltip("Esta es la información sobre herramientas del botón 2.")
    
    root.mainloop()
    

    Nota: Las informaciones sobre herramientas solo se muestran cuando el puntero del mouse permanece sobre el widget durante un tiempo predeterminado. Este tiempo de retraso se puede ajustar utilizando el método setToolTipDelay.

    Respondida el Jul 12, 2010 a las 05:34 - por Gemini

    Votos positivos: 0 | Votos negativos: 0