如何在窗口中显示结果(Tkinter) - " AttributeError"运行脚本后

时间:2017-11-18 12:33:52

标签: python python-3.x tkinter

我已经编写了一个脚本,它应根据不同的变量(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()

1 个答案:

答案 0 :(得分:2)

问题似乎是您最初将self.xpself.yp创建为DoubleVar个对象:

        self.xp = DoubleVar()
        self.yp = DoubleVar()

但是,您稍后将其替换为Entry小部件:

        self.xp = Entry(master)
        self.yp = Entry(master)

您可能想要做的是为Entry窗口小部件创建单独的对象,并将它们连接到self.xpself.yp,方法是将上面的最后两行替换为以下内容:

        self.xp_entry = Entry(master, textvariable=self.xp)
        self.yp_entry = Entry(master, textvariable=self.yp)

您还需要将self.xp.gridself.yp.grid的来电替换为self.xp_entry.gridself.yp_entry.grid上的等效来电,即:

        self.xp_entry.grid(row=9, column=1)
        self.yp_entry.grid(row=10, column=1)

一旦我对您的代码进行了这些更改,它似乎有效,因为我可以点击“Oblicz”'按钮,它会进行一些计算并更改XPYP文本字段的值,而不是引发异常。