动态绘制 Tkinter Canvas 对象的问题
一个问题:如何通过单击按钮动态绘制 Tkinter Canvas 对象?
该主题最初由 user339860(参见 1)作为一个由两部分组成的问题发布,但问题的第二部分尚未得到解决。我遇到了同样的问题,特别是我无法从按钮事件绘制到 Canvas 对象。回答这个问题将帮助两个人,我和用户339860;请看一下。
应用程序创建左右两个框架,第二个框架包含 Canvas 对象。我在第一帧中有一个按钮绑定到名为 drawRectangle 的函数/方法。该应用程序运行良好,它甚至使用 create_rectangle 方法在 Canvas 对象中绘制一个矩形,直到您单击该按钮。当您单击该按钮时,您会收到一条消息,其中包含以下内容;
tkinter_app_27Nov2010.py”,第 25 行,在drawRectangle 中 self.myCan.create_rectangle(64,64,110,110,fill='蓝色') AttributeError:“NoneType”对象没有属性“create_rectangle”
我认为这可能与 Canvas 对象的范围有关,因此我创建了一个类级别变量集到无,但这并没有解决问题。我考虑过 Canvas 显示列表(参见 2),但是 Tk 手册页没有反映我可以找到的添加新对象的方法。
代码:
# tkinter_app_27Nov2010.py
from Tkinter import *
class Application(Frame):
myCan = None
def createWidgets(self):
uiFrame = Frame(self,width=300,height=30)
uiFrame.configure(background='#e0e0e0')
uiFrame.grid(row=0,column=0,sticky=N+S)
outputFrame = Frame(self,width=300,height=300,background='#C0C0C0')
outputFrame.grid(row=0,column=1)
newBtn = Button(uiFrame,text="testing",command=self.drawRectangle)
newBtn.grid(row=0,column=0)
fillLbl = Label(uiFrame,text='-').grid(row=1,sticky=N+S)
newLBL = Label(outputFrame,text="another testing",background='#C0C0C0')
newLBL.grid(row=0)
myCan = Canvas(outputFrame,width=300,height=300,borderwidth=1,relief='sunken')
myCan.grid(row=1)
myCan.create_rectangle(34,34,50,50,fill='red')
def drawRectangle(self):
self.myCan.create_rectangle(64,64,110,110,fill='blue')
def __init__(self,master):
Frame.__init__(self,master)
self.pack()
self.createWidgets()
root = Tk() myApp = 应用程序(主=根) root.title("Tkinter 测试!") myApp.mainloop()
必须有一种方法来获取 Tkinter Canvas 对象用来更新自身的“损坏/修复显示模型”(参见 3)的句柄。请帮忙!
参考文献:
stackoverflow.com/questions/2824041/dynamically-add-items-to-tkinter-canvas
effbot.org/tkinterbook/canvas.htm#performance-issues
One question: How do you dynamically draw to a Tkinter Canvas object from a button click?
This topic was posted originally by user339860 (see 1) as a two part question, but the second portion of the question has not yet been addressed. I'm experiencing the same problem, specifically I cannot draw to a Canvas object from a button event. Getting this question answered will help two people, myself and user339860; please take a look.
The application creates two frames positioned left and right, the second frame contains the Canvas object. I have a button in the first frame bound to a function/method named drawRectangle. The application runs fine, it even draws a rectangle in the Canvas object using the create_rectangle method, until you click the button. When you click the button you get a message with the following;
tkinter_app_27Nov2010.py", line 25, in drawRectangle
self.myCan.create_rectangle(64,64,110,110,fill='blue')
AttributeError: 'NoneType' object has no attribute 'create_rectangle'
I thought it might have something to do with the scope of the Canvas object, so I created a class level variable set to None, but that didn't fix the issue. I thought about the Canvas display list (see 2), but the Tk manual pages don't reflect a method of adding a new object that I could find.
CODE:
# tkinter_app_27Nov2010.py
from Tkinter import *
class Application(Frame):
myCan = None
def createWidgets(self):
uiFrame = Frame(self,width=300,height=30)
uiFrame.configure(background='#e0e0e0')
uiFrame.grid(row=0,column=0,sticky=N+S)
outputFrame = Frame(self,width=300,height=300,background='#C0C0C0')
outputFrame.grid(row=0,column=1)
newBtn = Button(uiFrame,text="testing",command=self.drawRectangle)
newBtn.grid(row=0,column=0)
fillLbl = Label(uiFrame,text='-').grid(row=1,sticky=N+S)
newLBL = Label(outputFrame,text="another testing",background='#C0C0C0')
newLBL.grid(row=0)
myCan = Canvas(outputFrame,width=300,height=300,borderwidth=1,relief='sunken')
myCan.grid(row=1)
myCan.create_rectangle(34,34,50,50,fill='red')
def drawRectangle(self):
self.myCan.create_rectangle(64,64,110,110,fill='blue')
def __init__(self,master):
Frame.__init__(self,master)
self.pack()
self.createWidgets()
root = Tk()
myApp = Application(master=root)
root.title("Tkinter Testing!")
myApp.mainloop()
There has to be a way to get a handle on the "damage/repair display model" (see 3) the Tkinter Canvas object uses to update itself. Please help!
References:
stackoverflow.com/questions/2824041/dynamically-add-items-to-tkinter-canvas
effbot.org/tkinterbook/canvas.htm#performance-issues
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个 Python 问题,而不是 tkinter 问题。您已在
createWidgets
中定义了局部变量,但尚未将它们设置为实例属性。为此,您需要使用 self.foo :请注意,您确实是正确的:问题与 Canvas 的范围有关。或者更准确地说,使用
myCan
变量的范围。如果您没有定义类变量myCan
,则查找self.myCan
将引发一个明显的AttributeError
。This is a Python problem, not a
tkinter
one. You have defined local variables insidecreateWidgets
, but you haven't set them as instance attributes. You need to useself.foo
for that:Notice that you are indeed correct: the problem is to do with the scope of the
Canvas
. Or more precisely, with the scope of themyCan
variable. If you hadn't defined the class variablemyCan
, the lookupself.myCan
would have raised a revealingAttributeError
.没有对象“self.myCan”。您必须先将其创建为画布对象或其他对象,然后才能使用它。您可能还需要根据您的操作调用 update_idletasks() 。
There is no object "self.myCan". You have to create it as a canvas object or whatever before you can use it. You may also have to call update_idletasks() depending on what you do.