导入ttkbootstrap后配置scrollregion触发bad screen distance错误
解决ttkbootstrap导入后Canvas设置scrollregion的"bad screen distance"错误
问题根源
Tkinter的scrollregion参数要求传入整数类型的屏幕距离,但导入ttkbootstrap后,Canvas的bbox()方法返回的坐标值会变为浮点数(原生tkinter中通常为整数),当计算后的bbox列表包含带小数点的数值时,传入configure(scrollregion=bbox)就会触发_tkinter.TclError: bad screen distance错误。
修复方案
在设置scrollregion前,将bbox列表中的每个值转换为整数,确保符合Tkinter的参数要求。
修改核心代码
将原来直接传入bbox的代码:
self.canvas.configure(scrollregion=bbox) # !! error occurs here !!
替换为:
# 将bbox所有元素转为整数 int_bbox = [int(coord) for coord in bbox] self.canvas.configure(scrollregion=int_bbox)
如果需要更精确的坐标控制,也可以用round()进行四舍五入:
int_bbox = [round(coord) for coord in bbox] self.canvas.configure(scrollregion=int_bbox)
完整修改后的show_image方法
def show_image(self, event=None): bbox1 = self.canvas.bbox(self.container) bbox1 = (bbox1[0] + 1, bbox1[1] + 1, bbox1[2] - 1, bbox1[3] - 1) bbox2 = (self.canvas.canvasx(0), self.canvas.canvasy(0), self.canvas.canvasx(self.canvas.winfo_width()), self.canvas.canvasy(self.canvas.winfo_height())) bbox = [ min(bbox1[0], bbox2[0]), min(bbox1[1], bbox2[1]), max(bbox1[2], bbox2[2]), max(bbox1[3], bbox2[3]) ] if bbox[0] == bbox2[0] and bbox[2] == bbox2[2]: bbox[0] = bbox1[0] bbox[2] = bbox1[2] if bbox[1] == bbox2[1] and bbox[3] == bbox2[3]: bbox[1] = bbox1[1] bbox[3] = bbox1[3] # 修复:将bbox转为整数列表 int_bbox = [int(coord) for coord in bbox] self.canvas.configure(scrollregion=int_bbox) x1 = max(bbox2[0] - bbox1[0], 0) y1 = max(bbox2[1] - bbox1[1], 0) x2 = min(bbox2[2], bbox1[2]) - bbox1[0] y2 = min(bbox2[3], bbox1[3]) - bbox1[1] if int(x2 - x1) > 0 and int(y2 - y1) > 0: x = min(int(x2 / self.imscale), self.width) y = min(int(y2 / self.imscale), self.height) image = self.image.crop((int(x1 / self.imscale), int(y1 / self.imscale), x, y)) imagetk = ImageTk.PhotoImage(image.resize((int(x2 - x1), int(y2 - y1)))) imageid = self.canvas.create_image( max(bbox2[0], bbox1[0]), max(bbox2[1], bbox1[1]), anchor='nw', image=imagetk ) self.canvas.lower(imageid) self.canvas.imagetk = imagetk
额外说明
- 该错误仅在容器部分超出可视区域时触发,此时计算后的
bbox会包含浮点数;ttkbootstrap的导入会改变Canvas坐标的返回类型,原生tkinter中缩放后的bbox通常仍是整数。 - 转换为整数后,既解决了错误,也完全符合Tkinter对
scrollregion参数的要求。
内容的提问来源于stack exchange,提问作者Ole Bleß
相关产品推荐
相关产品推荐

