Python TkinterTreectrl 拖动项目

2 投票
1 回答
811 浏览
提问于 2025-04-18 01:35

我正在用Python写一个程序,目的是让我能够浏览我收集的实验数据,同时查看与每个数据集相关的实验条件的元数据。

这个程序的核心是一个叫做 TkinterTreectrl 的小工具,它是 tk treectrl 的一个封装。

尽管我还是个编程新手,但到目前为止一切都运行得不错——我可以添加项目、删除项目、选择它们等等。

不过,我还搞不清楚怎么把项目拖动到树形结构的新位置。我在文档中找到了很多关于拖动图像的内容,现在我可以拖动一个诱人的虚线轮廓。但我找不到在拖放时会生成的事件。手册中最接近的内容是以下一组事件:

<Drag-begin>
<Drag-receive>
<Drag-end>: Generated whenever the user drag-and-drops a file into a
            directory. This event is generated by the filelist-bindings.tcl
            library code, which is not used by default.

我不知道怎么使用 "filelist-bindings.tcl 库代码",而且我也不确定这是否是正确的方法。

另外,我在想,解决这个问题的一个方法是把我的 Treectrl 小工具生成的每一个事件都发送到 stdout。有没有办法做到这一点?

这里的一个最小可工作示例可能太大,不太有用,但一小段代码可能会有所帮助:

    # add callbacks for Edit events

    self.t.notify_install('<Edit-begin>')
    self.t.notify_bind('<Edit-begin>', self.edit_begin)
    self.t.notify_install('<Edit-accept>')
    self.t.notify_bind('<Edit-accept>', self.edit_accept)
    self.t.notify_install('<Edit-end>')
    self.t.notify_bind('<Edit-end>', self.edit_end)

    # add callbacks for mouse clicks

    self.t.bind('<Button-1>', self.OnLeftClick)
    self.t.bind('<Button-3>', self.OnRightClick)

    # add callbacks for drag events

    self.t.notify_install('<Drag-begin>')
    self.t.bind('<Drag-begin>', self.OnDrag)
    self.t.notify_install('<Drag-recieve>')
    self.t.bind('<Drag-recieve>', self.OnDrag)
    self.t.notify_install('<Drag-end>')
    self.t.bind('<Drag-end>', self.OnDrag)

编辑事件和鼠标点击的回调工作得很好,但尝试绑定拖动事件时会出现 _tkinter.TclError: bad event type or keysym "Drag" 的错误。

1 个回答

0

虽然这个问题不是最新的,但你为什么用 self.t.bind 而不是 self.t.notify_bind 呢?

在我看来,这看起来像是 Michael 的 tktreecrtl 接口没有使用包装功能,而是试图直接将 <Drag-begin> 绑定到一个基于 tkinter.WidgetTreectrl 实例上。

  • 源代码摘录:

    class Treectrl(tkinter.Widget):

tkinter.Widget 没有办法找到一个 '' 事件,因为这个事件是在 tktreectrl 库内部生成的。所以你会遇到

错误的事件类型或键名 "Drag"

改用 self.t.notify_bind 应该能解决你的问题。

撰写回答