Tkinter错误:'NoneType对象没有属性寄存器'

时间:2016-05-01 18:59:07

标签: python matplotlib tkinter ttk tkinter-canvas

我在Python X,Y(2.7.10)中使用Tkinter和Matplotlib来创建一个程序,用户可以在其中输入粒子的某些属性,并绘制二次图,表示其轨迹,距离等。 ,我无法看到一个看似简单的验证输入框工作,他们应该只接受数字。以下代码片段是我在网上看到的验证的原始版本,但我无法在我的程序中使用它。在工作片段下面是我尝试将其集成到我的程序窗口中,用户可以在其中添加新粒子。我将整个(不完整的)程序放在最底层,以防万一。如果您能够提出任何其他方式来验证,甚至是非交互式的,那将非常受欢迎。感谢。

工作原始代码段

from tkinter import *

root = Tk()

def testVal(inStr,i,acttyp):
    ind=int(i)
    if acttyp == '1': #insert
        if not inStr[ind].isdigit():
            return False
    return True

entry = Entry(root, validate="key")
entry['validatecommand'] = (entry.register(testVal),'%P','%i','%d')
entry.pack()

root.mainloop()

我的计划中的非工作版本:

def testVal():
    global inStr,i,acttyp
    ind=int(i)
    if acttyp == '1': #insert
        if not inStr[ind].isdigit():
            return False
    return True

def AddNewPart():
    #global S, U, V, A, T, SInput, UInput, VInput, AInput, TInput
    global inStr,i,acttyp
    #SInp=()
    #UInp=()
    #VInp=()
    #AInp=()
    #TInp=()

    NewPartWind=Toplevel()
    NewPartWind.geometry("400x200+300+300")
    NewPartWind.wm_title("New Particle")
    NewPartWind.wm_style = Style()
    NewPartWind.wm_style.theme_use("clam")

    SLab=Label(NewPartWind, text="Distance Travelled (S)", foreground="blue", font=("helvetica", 8)).place(x=10,y=30)
    ULab=Label(NewPartWind, text="Initial Velocity (U)", foreground="blue", font=("helvetica", 8)).place(x=10,y=60)
    VLab=Label(NewPartWind, text="Final Velocity (V)", foreground="blue", font=("helvetica", 8)).place(x=10,y=90)
    ALab=Label(NewPartWind, text="Acceleration (A)", foreground="blue", font=("helvetica", 8)).place(x=10,y=120)
    TLab=Label(NewPartWind, text="Time Taken (T)", foreground="blue", font=("helvetica", 8)).place(x=10,y=150)

    SInp=Entry(NewPartWind, validate="key").place(x=140,y=30)
    SInp['validatecommand'] = (SInp.register(testVal),'%P','%i','%d')
    UInp=Entry(NewPartWind, validate="key").place(x=140,y=60)
    UInp['validatecommand'] = (UInp.register(testVal),'%P','%i','%d')
    VInp=Entry(NewPartWind, validate="key").place(x=140,y=90)
    VInp['validatecommand'] = (VInp.register(testVal),'%P','%i','%d')
    AInp=Entry(NewPartWind, validate="key").place(x=140,y=120)
    AInp['validatecommand'] = (AInp.register(testVal),'%P','%i','%d')
    TInp=Entry(NewPartWind, validate="key").place(x=140,y=150)
    TInp['validatecommand'] = (TInp.register(testVal),'%P','%i','%d')

    SOk = Button(NewPartWind, text="Ok").place(x=290, y=25)
    UOk = Button(NewPartWind, text="Ok").place(x=290, y=55)
    VOk = Button(NewPartWind, text="Ok").place(x=290, y=85)
    AOk = Button(NewPartWind, text="Ok").place(x=290, y=115)
    TOk = Button(NewPartWind, text="Ok",).place(x=290, y=145)

完整(不完整)计划:

from Tkinter import *
from ttk import *
from decimal import *
#global S, U, V, A, T, SInput, UInput, VInput, AInput, TInput
global inStr,i,acttyp
S=0.0
U=0.0
V=0.0
A=0.0
T=0.0
#SInput=()
#UInput=()
#VInput=()
#AInput=()
#TInput=()

class MainMenu(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)   

        self.parent = parent
        self.initUI()


    def initUI(self):

        self.parent.title("MechSim 0.2")
        self.style = Style()
        self.style.theme_use("clam")

        self.pack(fill=BOTH, expand=True)

        StartButton = Button(self, text="New Simulation", command=create_window).place(x=50, y=60)
        ExampleButton = Button(self, text="Example Simulation", command=create_window).place(x=50, y=110)
        ExitButton = Button(self, text="Exit MechSim", command=self.end).place(x=50, y=160)
        Title = Label(self, text="MechSim 0.2", foreground="blue", font=("helvetica", 20)).place(x=300, y=50)

    def end(self):
        quit()

def create_window():
    global canvas
    import matplotlib
    matplotlib.use('TkAgg')
    from matplotlib.figure import Figure
    from numpy import arange, sin, pi
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
    from matplotlib.backend_bases import key_press_handler

    mainwind = Toplevel()
    mainwind.geometry("800x500+300+300")
    mainwind.wm_title("MechSim Simulator")
    mainwind.wm_style = Style()
    mainwind.wm_style.theme_use("clam")
    Title = Label(mainwind, text="MechSim 0.2", foreground="blue", font=("helvetica", 20)).place(x=620, y=7)

    f = matplotlib.figure.Figure(figsize=(5, 4), dpi=100)
    a = f.add_subplot(111)
    t = arange(0.0, 3.0, 0.01)
    s = sin(2*pi*t)

    a.plot(t,s)
    a.set_xlabel('Horizontal Distance (Metres)')
    a.set_ylabel('Vertical Distance (Metres)')

    import matplotlib.pyplot as plt
    fig, ax = plt.subplots()
    ax.set_xlim(0,1000)
    ax.set_ylim(0,1000)
    canvas = FigureCanvasTkAgg(f, master=mainwind)
    canvas.show()

    canvas.get_tk_widget().place(x=270, y=50)
    f.subplots_adjust(left=0.16, bottom=0.14)

    NewPartButton = Button(mainwind, text ="Add New Particle", command=AddNewPart).place(x=50,y=50)

    toolbar = NavigationToolbar2TkAgg(canvas,mainwind)
    toolbar.update()

def testVal():
    global inStr,i,acttyp
    ind=int(i)
    if acttyp == '1': #insert
        if not inStr[ind].isdigit():
            return False
    return True


def AddNewPart():
    #global S, U, V, A, T, SInput, UInput, VInput, AInput, TInput
    global inStr,i,acttyp
    #SInp=()
    #UInp=()
    #VInp=()
    #AInp=()
    #TInp=()

    NewPartWind=Toplevel()
    NewPartWind.geometry("400x200+300+300")
    NewPartWind.wm_title("New Particle")
    NewPartWind.wm_style = Style()
    NewPartWind.wm_style.theme_use("clam")

    SLab=Label(NewPartWind, text="Distance Travelled (S)", foreground="blue", font=("helvetica", 8)).place(x=10,y=30)
    ULab=Label(NewPartWind, text="Initial Velocity (U)", foreground="blue", font=("helvetica", 8)).place(x=10,y=60)
    VLab=Label(NewPartWind, text="Final Velocity (V)", foreground="blue", font=("helvetica", 8)).place(x=10,y=90)
    ALab=Label(NewPartWind, text="Acceleration (A)", foreground="blue", font=("helvetica", 8)).place(x=10,y=120)
    TLab=Label(NewPartWind, text="Time Taken (T)", foreground="blue", font=("helvetica", 8)).place(x=10,y=150)

    SInp=Entry(NewPartWind, validate="key").place(x=140,y=30)
    SInp['validatecommand'] = (SInp.register(testVal),'%P','%i','%d')
    UInp=Entry(NewPartWind, validate="key").place(x=140,y=60)
    UInp['validatecommand'] = (UInp.register(testVal),'%P','%i','%d')
    VInp=Entry(NewPartWind, validate="key").place(x=140,y=90)
    VInp['validatecommand'] = (VInp.register(testVal),'%P','%i','%d')
    AInp=Entry(NewPartWind, validate="key").place(x=140,y=120)
    AInp['validatecommand'] = (AInp.register(testVal),'%P','%i','%d')
    TInp=Entry(NewPartWind, validate="key").place(x=140,y=150)
    TInp['validatecommand'] = (TInp.register(testVal),'%P','%i','%d')

    SOk = Button(NewPartWind, text="Ok").place(x=290, y=25)
    UOk = Button(NewPartWind, text="Ok").place(x=290, y=55)
    VOk = Button(NewPartWind, text="Ok").place(x=290, y=85)
    AOk = Button(NewPartWind, text="Ok").place(x=290, y=115)
    TOk = Button(NewPartWind, text="Ok",).place(x=290, y=145)

#def CheckSInp():
    #S=SInput
    #print S

    #SInput = SInp.get()
    #try:
        #Decimal(SInput)
    #xcept InvalidOperation:
        #SInput.set("Enter a number")
    #return SInput, SInp

def main():

    root = Tk()
    root.geometry("500x300+300+300")
    app = MainMenu(root)
    root.mainloop()

if __name__ == '__main__':
    main()  

1 个答案:

答案 0 :(得分:1)

在第二个代码中:

SInp=Entry(NewPartWind, validate="key").place(x=140,y=30)

您在新创建的Entry上调用place()方法,返回None。你应该:

SInp=Entry(NewPartWind, validate="key")
SInp.place(x=140,y=30)

首先创建小部件,然后将其放置在所有Entry和其他小部件中,例如Button。