【问题标题】:Python Tkinter - Can only unbind and rebind Button-1 oncePython Tkinter - 只能取消绑定和重新绑定 Button-1 一次
【发布时间】:2019-12-25 19:35:11
【问题描述】:

我正在尝试停用链接到父函数的按钮 1。我需要重新分配按钮 1 以在画布上移动图像。第一次执行代码时一切正常。我第二次收到此错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1540, in __call__
    return self.func(*args)
  File "./wman2", line 244, in move_window
    MoveWindow(mycanvas, _item_id, _canvas_xy, _b1_bind, popup)
  File "./wman2", line 256, in __init__
    self.canvas.unbind("<ButtonPress-1>", self.b1_bind)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1102, in unbind
    self.deletecommand(funcid)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 450, in deletecommand
    self.tk.deletecommand(name)
TclError: can't delete Tcl command

代码:

我已将产生以下错误的代码注释掉:

def move_window ():
    global _b1_bind, popup
    ''' Can only move a window, not a monitor or entire canvas '''
    if _item_type == "Window" :
        MoveWindow(mycanvas, _item_id, _canvas_xy, _b1_bind, popup)

    else :
        display_info()

class MoveWindow:
    ''' Drag image on canvas '''

    def __init__(self, canvas, item, coords, b1_bind, func_bind):
        self._drag_data = {"x": 0, "y": 0, "item": None}
        self.item = item
        self.coords = coords
        self.canvas = canvas
        self.b1_bind = b1_bind
        self.func_bind = func_bind
#        self.canvas.unbind("<ButtonPress-1>", self.b1_bind)
        self.p_bind = self.canvas.bind("<ButtonPress-1>", \
                                       self.on_image_press, "+")
        self.r_bind = self.canvas.bind("<ButtonRelease-1>", \
                                       self.on_image_release, "+")
        self.m_bind = self.canvas.bind("<B1-Motion>", \
                                       self.on_image_motion, "+")

    def on_image_press(self, event):
        '''Begining drag of an object'''
        root.config(cursor='hand1')
        # record the item and its location
        self._drag_data["item"] = self.item
        self._drag_data["x"] = self.coords[0]
        self._drag_data["y"] = self.coords[1]
        ''' Initial call in case mouse off image '''

    def on_image_release(self, event):
        '''End drag of an object'''
        root.config(cursor='')
        self.canvas.unbind("<ButtonPress-1>", self.p_bind)
        self.canvas.unbind("<ButtonRelease-1>", self.r_bind)
        self.canvas.unbind("<B1-Motion>", self.m_bind)
#        self.b1_bind = self.canvas.bind("<Button-1>", self.func_bind, "+")

    def on_image_motion(self, event):
        '''Handle dragging of an object'''
        # compute how much the mouse has moved
        delta_x = event.x - self._drag_data["x"]
        delta_y = event.y - self._drag_data["y"]
        # move the object the appropriate amount
        self.canvas.move(self._drag_data["item"], delta_x, delta_y)
        # record the new position
        self._drag_data["x"] = event.x
        self._drag_data["y"] = event.y

在代码下面:

# attach popup to canvas
menu.bind("<FocusOut>", popup_focus_out)
_b3_bind = mycanvas.bind("<Button-3>", popup, "+")
# Button 1 conflicts with MoveWindow()
_b1_bind=None
#_b1_bind = mycanvas.bind("<Button-1>", popup, "+")

总结

我不得不注释掉的三行是:

_b1_bind = mycanvas.bind("<Button-1>", popup, "+")
self.canvas.unbind("<ButtonPress-1>", self.b1_bind)
self.b1_bind = self.canvas.bind("<Button-1>", self.func_bind, "+")

目前我唯一的选择是根本不让父函数使用按钮 1。我认为问题在于第一次将按钮 1 重新分配给父按钮 ID 更改并需要重新分配给全局变量 _b1_bind 但我不知道该怎么做?

学分: Code 来自 Brian Oakley。

【问题讨论】:

  • @stovfl 是的,我的历史上有过这样的经历:第一次成功取消绑定:Starting value: 140585244928592popup 第一次成功重新绑定:Ending value: 140585244928592popup第二次取消绑定导致程序崩溃:Starting value: 140585244928592popup跨度>
  • “第二次解除绑定140585244928592popup:你不能.unbind(...两次使用相同的iid。为了监控做self.br_bind = None在.unbind(...之后
  • @stovfl 我想你的意思是self.b1_bind = None?我想我可以再次取消绑定它,因为它是第二次重新创建的:self.b1_bind = self.canvas.bind("&lt;Button-1&gt;", self.func_bind, "+")

标签: python class tkinter global-variables


【解决方案1】:

感谢stovfl 的帮助,它现在可以正常工作了。

解决方法是将_b1_bind从全局变量改为封装在mycanvas内的变量。

第一步是改变这一行:

_b1_bind = mycanvas.bind("<Button-1>", popup, "+")

收件人:

mycanvas.b1_bind = mycanvas.bind("<ButtonPress-1>", popup, "+")

现在绑定按钮的 ID 不再是全局变量,而是mycanvas 范围变量的一部分。

下一步是更改 unbind from:

self.canvas.unbind("<ButtonPress-1>", self.b1_bind)

收件人:

self.canvas.unbind("<ButtonPress-1>", self.canvas.b1_bind)

记住canvas 是MoveWindow 类的参数,现在用以下方式调用:

MoveWindow(mycanvas, _item_id, _canvas_xy, popup)

并收到:

def __init__(self, canvas, item, coords, func_bind):

要更改的最后一行是:

self.b1_bind = self.canvas.bind("<Button-1>", self.func_bind, "+")

改为:

self.canvas.b1_bind = self.canvas.bind("<ButtonPress-1>", \
                                       self.func_bind, "+")

【讨论】:

    猜你喜欢
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    相关资源
    最近更新 更多