web-dev-qa-db-ja.com

Tkinterでツールチップを表示するにはどうすればよいですか?

ツールチップとは、一定期間マウスをウィジェットの上に置いたときにポップアップ表示されるテキストです。

tkinter Pythonアプリケーションにツールチップメッセージを追加するにはどうすればよいですか?

Example of tooltip

37
rectangletangle

Tkinterの Pmw.BalloonPmw toolkit のクラスは、ツールヒントを描画します。

Tkinterでツールヒントを表示するために使用されるIDLEのコードを適応させる ブログ投稿 もご覧ください。

17
ars

ars で言及された ブログ投稿 のコードを試しました IDLE lib のコードも試しました。

どちらも機能していましたが、IDLEのツールチップのサイズが制限されていて(手動で新しい行を個別のリストとして入力しなければなりませんでした)、ヒントがブログの投稿のコードにすぐに表示されていました。

だから私は両者のハイブリッドを作りました。ラップの長さとホバー時間を指定できます。それぞれに制限はありません。

""" 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("<Enter>", self.enter)
        self.widget.bind("<Leave>", self.leave)
        self.widget.bind("<ButtonPress>", 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()

スクリーンショット:

Example of hovertext

34
crxguy52

Windows 7を使用しているため、Pythonインストールにはおそらく Tix が含まれています。Tix.Balloonウィジェットを使用してください サンプルコード が存在しますPythonソースツリー内。

基本的には、Tix.Balloonウィジェットを作成し、その.bind_widgetメソッドを介して他のウィジェットにバインドし、balloonmsg引数を使用してバルーンメッセージを提供します。

11
tzot

まず、私は本当に気に入っています Alberto Vassenaのツールチップ と彼の投稿にこのバグ修正を加えてコメントしようとしましたが、新しいユーザーとして、コメントするのに十分なポイントがないので、答えを出す。これが許容できることを願っています。

Alberto Vassenaの優れた答え に非常に小さなバグがあり、ツールヒントが改善されました。

バグ:実際のラベルについて、彼のコードはtk.Labelではなくttk.Labelを呼び出します。これにより、ツールチップボックスがレンダリングされますが、別のマウスの移動やキーボードイベントなどのUIイベントが発生するまで、実際のテキストはレンダリングされません。

完全なコピーと貼り付けのための修正されたコードは次のとおりです。

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("<Enter>", self.onEnter)
        self.widget.bind("<Leave>", self.onLeave)
        self.widget.bind("<ButtonPress>", 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()
8
Erik Bethke

Tixウィジェットは基本的にサポートされておらず、通常は多くの問題を引き起こすため、Tixウィジェットの使用はお勧めしません。

以下は、Pythonのidlelibモジュールから直接取得したツールチップの example です。

# 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("<Enter>", self.enter)
        self._id2 = self.button.bind("<Leave>", self.leave)
        self._id3 = self.button.bind("<ButtonPress>", 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)

モジュールを直接インポートして使用することもできます:

from idlelib.ToolTip 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()

Python 3.4を使用しています。他のPythonのディストリビューションにこのToolTipモジュールが含まれていない可能性があります。

8
nbro

Tooltipクラスを変更しましたcrxguy52が提案しました。次のクラスは、インスタンス化する必要があるほとんどすべての場合に機能するはずです:[〜#〜] nw [〜#〜] [〜#〜] n [〜#〜][〜#〜] ne [〜#〜][〜 #〜] e [〜#〜][〜#〜] se [〜#〜][〜#〜 ] s [〜#〜][〜#〜] sw [〜#〜][〜#〜] w [〜#〜]

私のクラスが現在管理していない唯一のケースは、ツールチップが画面全体よりも単に高い場合です(おそらく非常にまれですが、手動でより大きいwraplengthもそのケースをすぐに解決できます)。

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("<Enter>", self.onEnter)
        self.widget.bind("<Leave>", self.onLeave)
        self.widget.bind("<ButtonPress>", 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。私は here aCanvasTooltipクラスを投稿しました。これにより、ツールチップをtkinter Canvas内で作成されたアイテムにバインドできます。

5
Alberto Vassena