首页 > 解决方案 > 试图移动一个对象并使用 Tkinter 作为 GUI,但是当有多个类的实例时它不起作用

问题描述

好吧,在这个项目之前,我从未真正使用过 Python。我这样做是因为这是老师的作业(即使我们从未上过 Python 课也很难),当然,因为学习一门新语言总是好的。

无论如何,此代码按预期工作,直到我添加AND该类的另一个实例。当我在我的代码中添加它时,事情变得疯狂。如果您能检查我的代码在有和没有AND类的两个测试实例的情况下如何工作,我将不胜感激。虽然我们正在这样做,但如果你们中的一个人/女孩能告诉我如何让AND按钮创建一个新的类实例,我将非常感激(例如在 c++ 中我会使用 new AND,当我按下按钮时我想要类似的东西)。

编辑:正如有人指出的那样,我还不够清楚。我所说的事情变得疯狂的意思是,当我添加超过 1 个类的实例时,我尝试执行的单击和拖动功能不再正常工作。单击和拖动不再适用于一个正方形,而对于另一个正方形,只要我绕过它,它就会跟随我的鼠标,即使我没有点击。我真的相信这是因为我有这个 int init函数:

   self.workspace.tag_bind(self.patrat,"<Enter>",self.whileInside)
   workspace.bind("<ButtonRelease-1>",self.onRelease)

我认为它不属于那里,但我真的不知道如何设计我的代码以及把它放在哪里,如果这是问题的话

到目前为止,这是我的代码:

import tkinter as tk
from tkinter import*

def doNothing():
    print("nothing happens bro")

root = Tk()

#========= Drop down menu/toolbar
menu = Menu(root)
root.config(menu=menu)

subMenu = Menu(menu)
menu.add_cascade(label="file", menu=subMenu)
subMenu.add_command(label="New Project...",command=doNothing)
subMenu.add_command(label="New",command=doNothing)
subMenu.add_separator()
subMenu.add_command(label="exit",command=doNothing)

editMenu = Menu(menu)
menu.add_cascade(label="edit", menu=editMenu)
editMenu.add_command(label="redo", command=doNothing)

#========Canvas
workspace=tk.Canvas(root, width=740, height=540,bg="white")
workspace.grid(row=0,column=1)

#====DRAW FUNCTIONS
# Draw rectangle
class AND():

    def __init__(self):
       x=10
       y=10
       self.workspace=workspace
       self.patrat = workspace.create_rectangle(x , y , x + 40 , y + 40,fill = "blue")
       self.workspace.tag_bind(self.patrat,"<Enter>",self.whileInside)
       print("self.workspace.tag_bind(self.patrat,<Enter>,self.whileInside)")
       workspace.bind("<ButtonRelease-1>",self.onRelease)
       print("  workspace.bind(<ButtonRelease-1>,self.onRelease)")

    def whileInside(self,event):
        self.workspace.tag_bind(self.patrat,"<Button-1>",self.onClick)
        print("self.workspace.tag_bind(self.patrat,<Button-1>,self.onClick)")

    def onClick(self,event):
        self.workspace.tag_bind(self.patrat,"<Motion>", self.callback)
        print("self.workspace.tag_bind(self.patrat,<Motion>, self.callback)")

    def onRelease(self,event):
        self.workspace.tag_unbind(self.patrat,"<Enter>")
        print(" self.workspace.tag_unbind(self.patrat,<Enter>)")
        self.workspace.tag_unbind(self.patrat,"<Button-1>")
        print("self.workspace.tag_unbind(self.patrat,<Button-1>)")
        self.workspace.tag_unbind(self.patrat,"<Motion>")
        print(" self.workspace.tag_unbind(self.patrat,<Motion>)")

    def callback(self,event):
        x, y = event.x, event.y
        self.workspace.coords(self.patrat, x, y, x + 40, y + 40)


test=AND()
test2=AND()

#========Left Frame
frame= Frame(root)
frame.grid(row = 0, column = 0, sticky = "n")

leftButton1 = Button(frame,text = "AND",width = 10).grid(row = 1, column = 0)
leftButton2 = Button(frame,text = "OR",width = 10).grid(row = 2, column = 0)
leftButton3 = Button(frame,text = "XOR",width = 10).grid(row = 3, column = 0)
leftButton4 = Button(frame,text = "XNOR",width = 10).grid(row = 4, column = 0)
leftButton5 = Button(frame,text = "NOT",width = 10).grid(row = 5, column = 0)

root.mainloop()

标签: pythontkinter

解决方案


问题是bind命令(不是tag_bind)不添加命令,它替换了命令。因此,当您的第二个实例调用 时workspace.bind("<ButtonRelease-1>",self.onRelease),它会从第一个实例中删除它。要添加命令,您需要可选的第三个参数,如下所示:workspace.bind("<ButtonRelease-1>",self.onRelease, '+')

但是,有一种更简单的方法可以实现您想要的。该事件还包括有关鼠标按钮的信息。因此,只需永久绑定到运动并在移动前检查鼠标按钮:

class AND():
    def __init__(self):
        x=10
        y=10
        self.workspace=workspace
        self.patrat = workspace.create_rectangle(x , y , x + 40 , y + 40,fill = "blue")
        self.workspace.tag_bind(self.patrat,"<Motion>",self.on_motion)

    def on_motion(self, event):
        if event.state & 256: # if the left mouse button is down
            x, y = event.x, event.y
            self.workspace.coords(self.patrat, x, y, x + 40, y + 40)

推荐阅读