python - 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 。这个问题有什么解决办法吗?
解决方案
感谢@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)
推荐阅读
- java - 使用 AES 算法加密和解密大文件
- javascript - 在 SparkAR 中获取纹理像素的 alpha 值
- c++ - 使用 Unity 对多个 HoloLense 进行全息远程处理
- docker - 有没有办法将 hadolint 用于多个 dockerfile?
- flutter - 有没有办法在轮播中添加许多 yt 视频并在 Flutter 中水平滑动(延迟加载)?
- postgresql - postrges 中大型查询字符串的优化
- node.js - 为什么我收到错误 mongo.db 聚合?
- java - 有效的 XML Unicode 字符
- python - 当我尝试在 Python3 的函数中打印全局变量时出错
- shader - 如何使用 HLSL 着色器裁剪和显示纹理表的特定图块?