Python Tkinter:使用鼠标滚轮滚动画布
我在一个画布里创建了一棵树,并且我让鼠标滚轮可以上下滚动。
但是,我该如何防止在树的内容没有超过画布大小时进行滚动呢?(树的内容可能会因为展开而超过画布的大小)
请运行以下代码:
from Tkinter import Tk, Frame, BOTH, Canvas
from xml.dom.minidom import parseString
from idlelib.TreeWidget import TreeItem, TreeNode
class DomTreeItem(TreeItem):
def __init__(self, node):
self.node = node
def GetText(self):
node = self.node
if node.nodeType == node.ELEMENT_NODE:
return node.nodeName
elif node.nodeType == node.TEXT_NODE:
return node.nodeValue
def IsExpandable(self):
node = self.node
return node.hasChildNodes()
def GetSubList(self):
parent = self.node
children = parent.childNodes
prelist = [DomTreeItem(node) for node in children]
itemlist = [item for item in prelist if item.GetText().strip()]
return itemlist
data = '''
<top>
<b>
<c>d</c>
<c>e</c>
</b>
<b>
<c><c><c><c><c>f</c></c></c></c></c>
<c><c><c><c><c>f</c></c></c></c></c>
<c><c><c><c><c>f</c></c></c></c></c>
</b>
</top>
'''
class Application(Frame):
def __init__(self, parent):
Frame.__init__(self, parent, background = "white")
parent.configure(bg = "black")
self.pack(fill = BOTH, expand = True, padx = 20, pady = 20)
self.parent = parent
self.parent.geometry('%dx%d+%d+%d' % (700, 700, 0, 0))
self.canvas = Canvas(self, bg = "white", bd = 10, highlightbackground = "black")
self.canvas.grid(column = 0, row = 0, rowspan = 2)
dom = parseString(data)
item = DomTreeItem(dom.documentElement)
node = TreeNode(self.canvas, None, item)
node.update()
node.expand()
self.parent.bind("<MouseWheel>", self.mouse_wheel) # Windows mouse wheel event
self.parent.bind("<Button-4>", self.mouse_wheel) # Linux mouse wheel event (Up)
self.parent.bind("<Button-5>", self.mouse_wheel) # Linux mouse wheel event (Down)
def mouse_wheel(self, event):
""" Mouse wheel as scroll bar """
direction = 0
# respond to Linux or Windows wheel event
if event.num == 5 or event.delta == -120:
direction = 1
if event.num == 4 or event.delta == 120:
direction = -1
self.canvas.yview_scroll(direction, "units")
def main():
root = Tk()
Application(root)
root.mainloop()
if __name__ == '__main__':
main()
2 个回答
0
我对树结构不太熟悉,但看起来它就是一堆标签。你可以测量这些标签的高度,然后和画布的高度进行比较,这样就能判断是否需要滚动页面。这种方法有点粗糙,但对我来说有效:
if self.canvas.winfo_reqheight() < len(self.canvas.winfo_children()) * self.canvas.winfo_children()[0].winfo_reqheight():
self.canvas.yview_scroll(direction, "units")
else:
pass
补充一下:如果觉得上面的代码太乱了,这里有个伪代码:
if CANVAS_HEIGHT < NUMBER_OF_LABELS * LABEL_HEIGHT:
scroll
1
你可以使用画布的 bbox
方法来获取在画布上绘制的物品的实际高度。bbox
会返回一个包含矩形信息的元组。你可以把这个矩形的高度和你的画布小部件的高度进行比较。
height = self.canvas.winfo_height()
_,_,_,items_height = self.canvas.bbox(Tkinter.ALL)
if (items_height < height):
direction = 0