首页 > 解决方案 > tkinter Listbox.bbox 方法在滚动列表框后返回 None

问题描述

我正在尝试制作一个列表框,在将光标移到它上面时显示提示,以启用我创建这样的类:

class CreateToolTip(object):

    def __init__(self, widget, text='widget info'):
        self.waittime = 300  # 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
        self.disp_thread = Thread

    def enter(self, event):
        self.schedule()
        global base_x, base_y
        base_x, base_y = event.x_root, event.y_root
        t = self.disp_thread(target=self.wait_and_disapr)
        t.start()

    def wait_and_disapr(self):
        sleep(3.5)
        self.hidetip()

    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(0)       # exception line
        x += base_x
        y += base_y
        # creates a toplevel window
        self.tw = tkinter.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 = tkinter.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()

然后我用 Listbox 对象初始化一个实例:

lstbox = tkinter.Listbox(*args, **kwargs)
lstbox_tip = CreateToolTip(lstbox, text=tip_info)

当列表框没有垂直滚动时,事情进展顺利,当光标移到列表框上时出现提示,但是当我向下滚动列表框时,提示没有正常显示并且发生以下异常:

> Traceback (most recent call last):
  File "...\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "...\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 749, in callit
    func(*args)
  File "DYRecorder-ttkVersion4.0-distribution.py", line 617, in showtip
    x, y, cx, cy = self.widget.bbox(0)
TypeError: cannot unpack non-iterable NoneType object

滚动列表框后,Listbox.bbox 方法似乎返回 None 。这个问题有什么解决办法吗?

标签: pythontkinterlistbox

解决方案


感谢@Bryan Oakley 对此链接的评论和解释,我得到了通过修改 showtip() 方法来显示何时显示列表框的提示,这是我添加的内容:

def showtip(self, event=None):
        x = y = 0
        index_lst = [0, 4, 8, 12, 16]  # my listbox has 20 elements
        for index in index_lst :
            if self.widget.bbox(page):
                x, y, cx, cy = self.widget.bbox(page)
                break
        x += base_x
        y += base_y
        self.tw = tkinter.Toplevel(self.widget)
        self.tw.wm_overrideredirect(True)
        self.tw.wm_geometry("+%d+%d" % (x, y))
        label = tkinter.Label(self.tw, text=self.text, justify='left',
                              background="#ffffff", relief='solid',
                              borderwidth=1, wraplength=self.wraplength)

推荐阅读