使用Python的tkinter,我试图通过扩展Canvas widget来创建自定义按钮和其他小部件。当用户与自定义画布小部件交互时,如何更改这些小部件被绘制在顶部?你知道吗
lift()适用于常规的tkinter按钮和其他小部件,但是当我尝试使用它来提升画布时会出现错误,因为Canvas has its own lift() method。Canvas的lift()不推荐用于Canvas,而支持tag\u raise()。但是,tag_raise()文档说它“不适用于窗口项”,这符合我的经验,并指导我改用lift()。我的大脑一直在追逐这个看似循环的文档,直到它引发了自己的StackOverflow异常,这让我不得不问你。你知道吗
下面是一些运行的基本代码,说明了我的问题。我已经包括了button3,这是一个可以按预期提升()的常规按钮。但是,如果单击custom\u按钮1,click\u处理程序将引发一个异常。你知道吗
from tkinter import Button, Canvas, Frame, Tk
from tkinter.constants import NW
class Example(Frame):
def __init__(self, root):
Frame.__init__(self, root)
self.canvas = Canvas(self, width=200, height=200, background="black")
self.canvas.grid(row=0, column=0, sticky="nsew")
self.button3 = Button(self.canvas, text="button3")
self.custom_button1 = MyCustomButton(self.canvas)
self.custom_button2 = MyCustomButton(self.canvas)
self.canvas.create_window(20, 20, anchor=NW, window=self.button3)
self.canvas.create_window(40, 40, anchor=NW, window=self.custom_button1)
self.canvas.create_window(34, 34, anchor=NW, window=self.custom_button2)
self.button3.bind("<Button-1>", self.click_handler)
self.custom_button1.bind("<Button-1>", self.click_handler)
self.custom_button2.bind("<Button-1>", self.click_handler)
def click_handler(self,event):
event.widget.lift() #raises exception if event.widget is a MyCustomButton
#note that Canvas.lift() is deprecated, but documentation
#says Canvas.tag_raise() doesn't work with window items
class MyCustomButton(Canvas):
def __init__(self, master):
super().__init__(master, width=40, height=25, background='blue')
if __name__ == "__main__":
root = Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
这适用于按钮3,但对于自定义按钮1,引发的异常是:
_tkinter.TclError: wrong # args: should be ".!example.!canvas.!mycustombutton2 raise tagOrId ?aboveThis?"
在这样的背景下,这个例外是有意义的帆布升降机()和Canvas.tag\u升起()通常用于按标记或id影响画布上的项目,而不是画布本身。我只是不知道如何更改画布本身的堆栈顺序,以便将其用作自定义小部件。你知道吗
我可以在画布上管理一堆定制的小部件,只需要一个画布来处理all绘图和all小部件的鼠标事件。我仍然可以为小部件创建类,但是它们不会从Canvas继承,而是接受Canvas参数。因此,添加类似于下面的代码,我必须编写类似的代码来提升、移动、确定是否对该按钮应用了单击事件、更改活动状态等等。你知道吗
def add_to_canvas(self, canvas, offset_x=0, offset_y=0):
self.button_border = canvas.create_rectangle(
offset_x + 0, offset_y + 0,
offset_x + 40, offset_y + 25
)
#create additional button features
不过,这项工作似乎与tkinter中已建立的编码范式背道而驰。此外,我相信这种方法会阻止我在其他窗口对象上方绘制这些自定义按钮。(根据create_window() documentation“您不能在小部件上绘制其他画布项目。”在这项工作中,所有自定义按钮都将是画布项目,因此如果我正确阅读了本文,就不能在其他小部件上绘制。)更不用说实现它所需的额外代码了。也就是说,我目前还没有更好的办法来实现这一点。你知道吗
提前感谢您的帮助!你知道吗
不幸的是,您在tkinter实现中偶然发现了一个bug。你可以用几种方法来解决这个问题。您可以创建一个方法来执行tkinter
lift
方法所执行的操作,也可以直接在tkinterMisc
类中调用该方法。你知道吗因为您正在创建自己的类,所以可以重写
lift
方法来使用这些方法中的任何一个。你知道吗下面是如何使用现有函数实现的。确保从tkinter导入
Misc
:下面是如何直接调用底层tk解释器:
这样,您就可以通过调用
lift
方法将一个按钮置于另一个按钮之上:相关问题 更多 >
编程相关推荐