Вопрос по mouseevent, tkinter, treeview, canvas, python – Python Tkinter: прокрутка холста с помощью MouseWheel

2

Я создал дерево внутри Canvas, и я также позволил MouseWheel прокручивать вверх и вниз.

Однако как предотвратить прокрутку, если содержимое дерева не превышает размер холста? (Содержимое дерева может быть больше размера холста при расширении)

Пожалуйста, запустите следующий код:

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   ответа
1

Вы можете использоватьbbox метод холста, чтобы получить фактическую высоту нарисованных элементов на холсте.bbox вернуть кортеж, определяющий прямоугольник. Вы можете сравнить его с высотой вашего виджета холста.

  height = self.canvas.winfo_height()
  _,_,_,items_height = self.canvas.bbox(Tkinter.ALL)
  if (items_height < height):
     direction = 0
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
Я расширил все, так что требуется прокрутка, но затем, когда я сверну все, он не должен прокручиваться. Таким образом, проблема решается до расширения, но возвращается после James the Great
Да, я тоже это понимаю, просто не знаю, как с этим бороться. James the Great
Благодарю. Кстати, в моем собственном коде я использовал sticky = 'NSWE' при размещении холста в моем фрейме. Поэтому не уверен, что отображаемый размер отличается от canvas.winfo_reqheight () James the Great
Я думаю, что проблема заключается в длине списка детей. Когда узлы расширяются, они растут, но когда они разрушаются, они не удаляются из списка. atlasologist
Ах. Я имел дело с небольшим расширенным списком, и я не принял это во внимание. Я подумаю об этом и отредактирую свой ответ, если что-нибудь придумаю. atlasologist

Похожие вопросы