我已经编写了一个脚本,它应根据不同的变量(xa,ya,xb,yb,xc,yc,xd,yd)计算交叉点(xp,yp),并在坐标系中绘制带有点的段。通常它有效,但有一个问题。我想在clicking按钮" Oblicz"之后在窗口Tkinter中显示我的结果(xp,yp),但是在实现self.xp.set(XP)
之后我收到错误AttributeError: Entry instance has no attribute 'set'
。这有什么问题?我该如何修改呢?
from Tkinter import *
import matplotlib.pyplot as plt
import numpy as np
import itertools
class Calculator:
def __init__(self, master):
self.master = master
master.title("Przecinanie prostych")
vcmd = master.register(self.validate) # we have to wrap the command
self.entry = Entry(master, validate="key", validatecommand=(vcmd,
'%P'))
self.zamknij_button = Button(master,
text='Zamknij',command=master.quit)
#draw result**
self.rysuj_button = Button(master, text=' Rysuj ',
command=lambda:self.draw())
#show result**
self.oblicz_button = Button(master, text=' Oblicz ',
command=lambda:self.update())
# LAYOUT ONLY
self.xp = DoubleVar()
self.yp = DoubleVar()
self.xa_label = Label(master, text="XA")
self.xa_label.grid(row=0)
self.ya_label = Label(master, text="YA")
self.ya_label.grid(row=1)
self.xb_label = Label(master, text="XB")
self.xb_label.grid(row=2)
self.yb_label = Label(master, text="YB")
self.yb_label.grid(row=3)
self.xc_label = Label(master, text="XC")
self.xc_label.grid(row=4)
self.yc_label = Label(master, text="YC")
self.yc_label.grid(row=5)
self.xd_label = Label(master, text="XD")
self.xd_label.grid(row=6)
self.yd_label = Label(master, text="YD")
self.yd_label.grid(row=7)
self.e7_label = Label(master, text="XP")
self.e7_label.grid(row=9)
self.e7 = Entry(master, textvariable = self.xp)
self.e7.grid(row = 9, column = 1)
self.e8_label = Label(master, text="YP")
self.e8_label.grid(row=10)
self.e8 = Entry(master, textvariable = self.yp)
self.e8.grid(row = 10, column = 1)
self.zamknij_button.grid(row=11, column=1, sticky=W, pady=5)
self.oblicz_button.grid(row=8, column=1, sticky=W, pady=4)
self.rysuj_button.grid(row=11, column = 2, sticky=W, pady=4)
self.xa = Entry(master)
self.ya = Entry(master)
self.xb = Entry(master)
self.yb = Entry(master)
self.xc = Entry(master)
self.yc = Entry(master)
self.xd = Entry(master)
self.yd = Entry(master)
self.xp = Entry(master)
self.yp = Entry(master)
self.xa.grid(row=0, column=1)
self.ya.grid(row=1, column=1)
self.xb.grid(row=2, column=1)
self.yb.grid(row=3, column=1)
self.xc.grid(row=4, column=1)
self.yc.grid(row=5, column=1)
self.xd.grid(row=6, column=1)
self.yd.grid(row=7, column=1)
self.xp.grid(row=9, column=1)
self.yp.grid(row=10, column=1)
self.xa.insert(10, 0)
self.ya.insert(10, 0)
self.xb.insert(10, 10)
self.yb.insert(10, 10)
self.xc.insert(10, 0)
self.yc.insert(10, 10)
self.xd.insert(10, 10)
self.yd.insert(10, 0)
def validate(self, new_text):
if not new_text: # the field is being cleared
self.xp.set(0)
return True
try:
self.xp.set(int(new_text))
return True
except ValueError:
return False
def update(self):
xa = float(self.xa.get())
ya = float(self.ya.get())
xb = float(self.xb.get())
yb = float(self.yb.get())
xc = float(self.xc.get())
yc = float(self.yc.get())
xd = float(self.xd.get())
yd = float(self.yd.get())
dXAB = xb - xa
dXCD = xd - xc
dXAC = xc - xa
dYAB = yb - ya
dYCD = yd - yc
dYAC = yc - ya
mian = dXAB * dYCD - dYAB * dXCD
t1 = (dXAC * dYCD - dYAC * dXCD) / mian
if mian == 0:
raise Exception('Brak przeciec')
XP = xa + t1 * dXAB
self.xp.set(XP)
print XP
YP = ya + t1 * dYAB
self.yp.set(YP)
print YP
def draw(self):
xa = float(self.xa.get())
ya = float(self.ya.get())
xb = float(self.xb.get())
yb = float(self.yb.get())
xc = float(self.xc.get())
yc = float(self.yc.get())
xd = float(self.xd.get())
yd = float(self.yd.get())
fig = plt.figure()
ax = fig.add_subplot(111)
plt.axis([-2, xd + 2, -2, yb + 2])
t1 = [[xa, ya], [xb, yb]]
t2 = [[xc, yc], [xd, yd]]
plt.plot(
*zip(*itertools.chain.from_iterable(itertools.combinations(t1, 2))),
color='blue', marker='o')
plt.plot(
*zip(*itertools.chain.from_iterable(itertools.combinations(t2, 2))),
color='green', marker='o')
ax.annotate('A', xy=(xa, ya), xytext=(xa-0.7, ya), fontsize=18)
ax.annotate('B', xy=(xb, yb), xytext=(xb - 0.7, yb), fontsize=18)
ax.annotate('C', xy=(xc, yc), xytext=(xc - 0.7, yc), fontsize=18)
ax.annotate('D', xy=(xd, yd), xytext=(xd + 0.3, yd), fontsize=18)
plt.show()
root = Tk()
my_gui = Calculator(root)
root.mainloop()
答案 0 :(得分:2)
问题似乎是您最初将self.xp
和self.yp
创建为DoubleVar
个对象:
self.xp = DoubleVar()
self.yp = DoubleVar()
但是,您稍后将其替换为Entry
小部件:
self.xp = Entry(master)
self.yp = Entry(master)
您可能想要做的是为Entry
窗口小部件创建单独的对象,并将它们连接到self.xp
和self.yp
,方法是将上面的最后两行替换为以下内容:
self.xp_entry = Entry(master, textvariable=self.xp)
self.yp_entry = Entry(master, textvariable=self.yp)
您还需要将self.xp.grid
和self.yp.grid
的来电替换为self.xp_entry.grid
和self.yp_entry.grid
上的等效来电,即:
self.xp_entry.grid(row=9, column=1)
self.yp_entry.grid(row=10, column=1)
一旦我对您的代码进行了这些更改,它似乎有效,因为我可以点击“Oblicz”'按钮,它会进行一些计算并更改XP
和YP
文本字段的值,而不是引发异常。