如何显示情节?

时间:2018-12-09 04:45:36

标签: python user-interface matplotlib tkinter

因此,我正在尝试创建此函数以绘制质量弹簧减震器系统的图,并且我们应该能够基本上更改所需的值,该函数的值和滑块也应影响该图,我我在尝试绘制我的函数时遇到麻烦。我正在尝试在PlotWindow函数中使用我的solveMBK函数的函数中出现错误,我不确定如何包括滑块中的值以及在启动窗口中输入的其他值。这是我的代码:

import tkinter as tk

from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)

from matplotlib.figure import Figure

import numpy as np


def solveMBK(inlist):

    x0 = inlist[0]
    dx0 = inlist[1]
    dt = inlist[2]
    m = inlist[3]
    b = inlist[4]
    k = inlist[5]
    tf = inlist[6]
    Z = inlist[7]

    t = np.arange(0,tf,dt)

    z0 = np.zeros_like(t)
    z1 = np.zeros_like(t)

    z0[0] = x0
    z1[0] = dx0

    for c in range(len(t)-1):
        z0[c+1] = z0[c] + z1[c]*dt
        z1[c+1] = z1[c] + ((ABradiobutton(Z,t[c]) - k*z0[c] - b*z1[c]) / m)

    x = z0

    return t,x

def ABradiobutton(Z, t):
    if Z == 1:
        A = float(A_entry.get())
        return A

    elif Z == 2:
        B = float(B_entry.get())
        return np.sin(B*t)

def PlotWindow():

    root1 = tk.Tk()

    root1.title("Plot")

    Mmin = float(Mmin_entry.get())

    Mmax = float(Mmax_entry.get())

    bmin = float(bmin_entry.get())

    bmax = float(bmax_entry.get())

    kmin = float(kmin_entry.get())

    kmax = float(kmax_entry.get())

    mscale = tk.Scale(root1, from_=Mmin, to=Mmax, label="m", bd=2, length=200, orient=tk.HORIZONTAL, command = funcPlot)

    mscale.set((Mmin+Mmax)/2)

    mscale.grid(row=1, column=0)

    bscale = tk.Scale(root1, from_=bmin, to=bmax, label="b", bd=2, length=200, orient=tk.HORIZONTAL, command = funcPlot)

    bscale.set((bmin+bmax)/2)

    bscale.grid(row=3, column=0)

    kscale = tk.Scale(root1, from_=kmin, to=kmax, label="k", bd=2, length=200, orient=tk.HORIZONTAL, command = funcPlot)

    kscale.set((kmin+kmax)/2)

    kscale.grid(row=5, column=0)

    tk.Label(root1, text = " ").grid(row=6, column=0)

    tk.Button(root1, text="Back", command=root1.destroy).grid(row=7, column=0)

    Graph_Frame = tk.Frame(root1)

    Graph_Frame.grid(row=2, column=2, columnspan=10, rowspan=10)

    Fig = Figure(figsize=(5.5,4))

    a = Fig.add_subplot(111)

    if Radio_Var == 1:
        t,x = solveMBK(str(mscale.get()), str(bscale.get()), str(kscale.get()), str(A_entry.get()), str(x0_Entry.get()), str(dxdt_Entry.get()), str(tfinal_entry.get()), str(dt_entry.get()))
        a.plot(t,x)

    # elif Radio_Var == 2:
    #     t,x = solveMBK()
    #     a.plot(t,x)

    tk.Label(Graph_Frame, text = "Mass-Spring-Damper Plot").pack()

    canvas = FigureCanvasTkAgg(Fig, Graph_Frame)

    canvas.draw()

    canvas.get_tk_widget().pack()

    toolbar = NavigationToolbar2Tk(canvas, Graph_Frame)

    toolbar.update()

    canvas.get_tk_widget().pack()



def CloseWindow():

    root.quit()

    root.destroy()

    exit()


def funcPlot(input_list, mscale, bscale, kscale, a, canvas, event=None):
    input_list[0]=float(x0_Entry.get())
    input_list[1]=float(dxdt_Entry.get())
    input_list[2]=float(dt_entry.get())
    input_list[3]=float(mscale.get())
    input_list[4]=float(bscale.get())
    input_list[5]=float(kscale.get())
    input_list[6]=float(tfinal_entry.get())
    input_list[7]=float(Radio_Var.get())

    data = solveMBK(input_list)

    a.plot(data[0], data[1])

    canvas.draw()

    return

root = tk.Tk()

root.title("Numerical solution of a second order differential equation")

tk.Label(root, text = "Differential Equation:").grid(row=0, column=0, sticky=tk.E)

tk.Label(root, text = "m d2x/dt2 + b dx/dt + kx = f(x)").grid(row=0, column=1)

x0_Start = tk.IntVar()

x0_Start.set("0")

x0_Entry = tk.Entry(root, width=7, textvariable = x0_Start)

tk.Label(root, text = "x(0) = ").grid(row=1, column=0, stick=tk.E), x0_Entry.grid(row=1, column=1, sticky=tk.W)

dxdt_Start = tk.IntVar()

dxdt_Start.set("0")

dxdt_Entry = tk.Entry(root, width=7, textvariable = dxdt_Start)

tk.Label(root, text = "dx(0)/dt= ").grid(row=2, column=0, sticky=tk.E), dxdt_Entry.grid(row=2, column=1, sticky=tk.W)

A_start = tk.IntVar()

A_start.set("1")

A_entry = tk.Entry(root, width=7, textvariable = A_start)

tk.Label(root, text = "A = ").grid(row=6, column=1, sticky=tk.E), A_entry.grid(row=6, column=2, sticky=tk.W)

B_start = tk.IntVar()

B_start.set("0")

B_entry = tk.Entry(root, width=7, textvariable=B_start)

tk.Label(root, text= "B =").grid(row=7,column=1, sticky=tk.E), B_entry.grid(row=7, column=2, sticky=tk.W)

tk.Label(root, text = " ").grid(row=5, column=0, sticky=tk.E)

Radio_Var = tk.IntVar()

tk.Radiobutton(root, text="A", value = 1, variable=Radio_Var).grid(row=6, column=1, sticky = tk.W)

tk.Radiobutton(root, text="sin(Bt)", value = 2, variable=Radio_Var).grid(row=7, column=1, sticky = tk.W)

Radio_Var.set(1)

tk.Label(root, text = "f(x) = ").grid(row=6, column=0, sticky=tk.E)

tk.Label(root, text = " ").grid(row=8, column=0, sticky=tk.E)

tfinal_start = tk.IntVar()

tfinal_start.set("10")

tfinal_entry = tk.Entry(root, width = 7, textvariable=tfinal_start)

tk.Label(root, text = "tfinal = ").grid(row=9, column=0, sticky=tk.E), tfinal_entry.grid(row=9, column=1, sticky=tk.W)

dt_start = tk.IntVar()

dt_start.set("0.001")

dt_entry = tk.Entry(root, width = 7, textvariable=dt_start)

tk.Label(root, text = "dt = ").grid(row=9, column=1, sticky=tk.E), dt_entry.grid(row=9, column=2, sticky=tk.W)

tk.Label(root, text = " ").grid(row=10, column=0, sticky=tk.E)

Mmin_start = tk.IntVar()

Mmin_start.set("1")

Mmin_entry = tk.Entry(root, width=7, textvariable=Mmin_start)

tk.Label(root, text = "Mmin = ").grid(row=11, column=0, sticky=tk.E), Mmin_entry.grid(row=11, column=1, sticky=tk.W)

Mmax_start = tk.IntVar()

Mmax_start.set("100")

Mmax_entry = tk.Entry(root, width=7, textvariable=Mmax_start)

tk.Label(root, text = "Mmax = ").grid(row=11,column=1, sticky=tk.E), Mmax_entry.grid(row=11, column=2, sticky=tk.W)

bmin_start = tk.IntVar()

bmin_start.set("1")

bmin_entry = tk.Entry(root, width=7, textvariable=bmin_start)

tk.Label(root, text = "bmin = ").grid(row=12, column=0, sticky=tk.E), bmin_entry.grid(row=12, column=1, sticky=tk.W)

bmax_start = tk.IntVar()

bmax_start.set("250")

bmax_entry = tk.Entry(root, width=7, textvariable=bmax_start)

tk.Label(root, text= "bmax = ").grid(row=12, column=1, sticky=tk.E), bmax_entry.grid(row=12,column=2,sticky=tk.W)

kmin_start = tk.IntVar()

kmin_start.set("1")

kmin_entry = tk.Entry(root, width=7, textvariable=kmin_start)

tk.Label(root, text= "kmin = ").grid(row=13, column=0, sticky=tk.E), kmin_entry.grid(row=13, column=1, sticky=tk.W)

kmax_start = tk.IntVar()

kmax_start.set("500")

kmax_entry = tk.Entry(root, width=7, textvariable=kmax_start)

tk.Label(root, text="kmax = ").grid(row=13, column=1, sticky=tk.E), kmax_entry.grid(row=13, column=2, sticky=tk.W)

tk.Button(root, text = "Quit", command=CloseWindow, width=10).grid(row=14, column=0)

tk.Button(root, text= "Plot", command=PlotWindow, width=10).grid(row=14, column=3)

root.mainloop()

任何帮助将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:0)

您正在将funcPlot作为command传递给Scale进行呼叫:

mscale = tk.Scale(root1, ..., command=funcPlot)

根据文档,command为:

  

每次移动滑块时都要调用的过程。这个   过程将被传递 one 参数,即新的小数位值。

但是您的funcPlot()函数需要使用六个参数,而不是使用一个参数:

def funcPlot(input_list, mscale, bscale, kscale, a, canvas, event=None):

哪个会导致错误:

TypeError: funcPlot() missing 5 required positional arguments: 'mscale', 'bscale', 'kscale', 'a', and 'canvas'

您需要重新考虑它应该如何工作。以下是我对您的代码的重做。我通过使用全局变量解决了上述问题,对此我并不感到骄傲。我还不得不重新设计您的情节嵌入Tk的方式,因为您当时无法使用:

import tkinter as tk
import numpy as np

from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure

def solveMBK(inlist):

    x0, dx0, dt, m, b, k, tf, Z = inlist

    t = np.arange(0, tf, dt)

    z0 = np.zeros_like(t)
    z1 = np.zeros_like(t)

    z0[0] = x0
    z1[0] = dx0

    for c in range(len(t) - 1):
        z0[c + 1] = z0[c] + z1[c] * dt
        z1[c + 1] = z1[c] + ((ABradiobutton(Z, t[c]) - k * z0[c] - b * z1[c]) / m)

    return t, z0

def ABradiobutton(Z, t):

    if Z == 1:
        A = float(A_entry.get())
        return A

    if Z == 2:
        B = float(B_entry.get())
        return np.sin(B * t)

def PlotWindow():
    global mscale, bscale, kscale, subplot, figure_canvas

    plot_window = tk.Toplevel(root)
    plot_window.title("Plot")

    Mmin = float(Mmin_entry.get())
    Mmax = float(Mmax_entry.get())

    bmin = float(bmin_entry.get())
    bmax = float(bmax_entry.get())

    kmin = float(kmin_entry.get())
    kmax = float(kmax_entry.get())

    mscale = tk.Scale(plot_window, from_=Mmin, to=Mmax, label="m", bd=2, length=200, orient=tk.HORIZONTAL, command=funcPlot)
    mscale.set((Mmin + Mmax) / 2)
    mscale.grid(row=1, column=0)

    bscale = tk.Scale(plot_window, from_=bmin, to=bmax, label="b", bd=2, length=200, orient=tk.HORIZONTAL, command=funcPlot)
    bscale.set((bmin + bmax) / 2)
    bscale.grid(row=3, column=0)

    kscale = tk.Scale(plot_window, from_=kmin, to=kmax, label="k", bd=2, length=200, orient=tk.HORIZONTAL, command=funcPlot)
    kscale.set((kmin + kmax) / 2)
    kscale.grid(row=5, column=0)

    tk.Label(plot_window, text=" ").grid(row=6, column=0)

    tk.Button(plot_window, text="Back", command=plot_window.destroy).grid(row=7, column=0)

    graph_frame = tk.Frame(plot_window)
    graph_frame.grid(row=2, column=2, columnspan=10, rowspan=10)

    figure = Figure(figsize=(5.5, 4))

    subplot = figure.add_subplot(111)

    if Radio_Var.get() == 1:
        t, x = solveMBK([float(mscale.get()), float(bscale.get()), float(kscale.get()), float(A_entry.get()), float(x0_Entry.get()), float(dxdt_Entry.get()), float(tfinal_entry.get()), float(dt_entry.get())])
        subplot.plot(t, x)

    # elif Radio_Var.get() == 2:
    #   t, x = solveMBK()
    #   subplot.plot(t, x)

    figure_canvas = FigureCanvasTkAgg(figure, master=graph_frame)
    figure_canvas.draw()
    figure_canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

    toolbar = NavigationToolbar2Tk(figure_canvas, graph_frame)
    toolbar.update()
    figure_canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

    tk.Label(graph_frame, text="Mass-Spring-Damper Plot").pack()

def CloseWindow():
    root.quit()
    root.destroy()
    exit()

def funcPlot(event):
    input_list = []

    input_list.append(float(x0_Entry.get()))
    input_list.append(float(dxdt_Entry.get()))
    input_list.append(float(dt_entry.get()))
    input_list.append(float(mscale.get()))
    input_list.append(float(bscale.get()))
    input_list.append(float(kscale.get()))
    input_list.append(float(tfinal_entry.get()))
    input_list.append(float(Radio_Var.get()))

    t, x = solveMBK(input_list)

    subplot.plot(t, x)

    figure_canvas.draw()

figure_canvas = subplot = mscale = bscale = kscale = None

root = tk.Tk()
root.title("Numerical solution of a second order differential equation")

tk.Label(root, text="Differential Equation:").grid(row=0, column=0, sticky=tk.E)
tk.Label(root, text="m d2x/dt2 + b dx/dt + kx = f(x)").grid(row=0, column=1)

tk.Label(root, text="x(0) = ").grid(row=1, column=0, stick=tk.E)

x0_Start = tk.IntVar()
x0_Start.set("0")
x0_Entry = tk.Entry(root, width=7, textvariable=x0_Start)
x0_Entry.grid(row=1, column=1, sticky=tk.W)

tk.Label(root, text="dx(0)/dt = ").grid(row=2, column=0, sticky=tk.E)

dxdt_Start = tk.IntVar()
dxdt_Start.set("0")
dxdt_Entry = tk.Entry(root, width=7, textvariable=dxdt_Start)
dxdt_Entry.grid(row=2, column=1, sticky=tk.W)

tk.Label(root, text=" ").grid(row=5, column=0, sticky=tk.E)

Radio_Var = tk.IntVar()
Radio_Var.set(1)
tk.Label(root, text="f(x) = ").grid(row=6, column=0, sticky=tk.E)
tk.Radiobutton(root, text="A", value=1, variable=Radio_Var).grid(row=6, column=1, sticky=tk.W)
tk.Label(root, text="A = ").grid(row=6, column=1, sticky=tk.E)

A_start = tk.IntVar()
A_start.set("1")
A_entry = tk.Entry(root, width=7, textvariable=A_start)
A_entry.grid(row=6, column=2, sticky=tk.W)

tk.Radiobutton(root, text="sin(Bt)", value=2, variable=Radio_Var).grid(row=7, column=1, sticky=tk.W)
tk.Label(root, text="B =").grid(row=7, column=1, sticky=tk.E)

B_start = tk.IntVar()
B_start.set("0")
B_entry = tk.Entry(root, width=7, textvariable=B_start)
B_entry.grid(row=7, column=2, sticky=tk.W)

tk.Label(root, text=" ").grid(row=8, column=0, sticky=tk.E)

tk.Label(root, text="tfinal = ").grid(row=9, column=0, sticky=tk.E)

tfinal_start = tk.IntVar()
tfinal_start.set("10")
tfinal_entry = tk.Entry(root, width=7, textvariable=tfinal_start)
tfinal_entry.grid(row=9, column=1, sticky=tk.W)

tk.Label(root, text="dt = ").grid(row=9, column=1, sticky=tk.E)

dt_start = tk.IntVar()
dt_start.set("0.001")
dt_entry = tk.Entry(root, width=7, textvariable=dt_start)
dt_entry.grid(row=9, column=2, sticky=tk.W)

tk.Label(root, text=" ").grid(row=10, column=0, sticky=tk.E)

tk.Label(root, text="Mmin = ").grid(row=11, column=0, sticky=tk.E)

Mmin_start = tk.IntVar()
Mmin_start.set("1")
Mmin_entry = tk.Entry(root, width=7, textvariable=Mmin_start)
Mmin_entry.grid(row=11, column=1, sticky=tk.W)

tk.Label(root, text="Mmax = ").grid(row=11, column=1, sticky=tk.E)

Mmax_start = tk.IntVar()
Mmax_start.set("100")
Mmax_entry = tk.Entry(root, width=7, textvariable=Mmax_start)
Mmax_entry.grid(row=11, column=2, sticky=tk.W)

tk.Label(root, text="bmin = ").grid(row=12, column=0, sticky=tk.E)

bmin_start = tk.IntVar()
bmin_start.set("1")
bmin_entry = tk.Entry(root, width=7, textvariable=bmin_start)
bmin_entry.grid(row=12, column=1, sticky=tk.W)

tk.Label(root, text="bmax = ").grid(row=12, column=1, sticky=tk.E)

bmax_start = tk.IntVar()
bmax_start.set("250")
bmax_entry = tk.Entry(root, width=7, textvariable=bmax_start)
bmax_entry.grid(row=12, column=2, sticky=tk.W)

tk.Label(root, text="kmin = ").grid(row=13, column=0, sticky=tk.E)

kmin_start = tk.IntVar()
kmin_start.set("1")
kmin_entry = tk.Entry(root, width=7, textvariable=kmin_start)
kmin_entry.grid(row=13, column=1, sticky=tk.W)

tk.Label(root, text="kmax = ").grid(row=13, column=1, sticky=tk.E)

kmax_start = tk.IntVar()
kmax_start.set("500")
kmax_entry = tk.Entry(root, width=7, textvariable=kmax_start)
kmax_entry.grid(row=13, column=2, sticky=tk.W)

tk.Button(root, text="Quit", command=CloseWindow, width=10).grid(row=14, column=0)
tk.Button(root, text="Plot", command=PlotWindow, width=10).grid(row=14, column=3)

root.mainloop()

enter image description here