首页 > 解决方案 > 使用 .get 集成一个函数

问题描述

我正在使用 tkinter 和 scipy 来制作一个集成功能的程序,让我们说关于 x。这是我的代码:

def newtest1():
intwindow = Tk()

Label(intwindow, text = 'enter here', font = ('Symbol')).grid(row=0)
Label(intwindow, text = 'enter upper bound', font = ('Symbol')).grid(row=1)
Label(intwindow, text = 'enter lower bound', font = ('Symbol')).grid(row=2)

get1 = IntVar()
Entry(intwindow, textvariable = get1).grid(row=0, column=1)

getupper = IntVar()
Entry(intwindow, textvariable = getupper).grid(row=1, column=1)

getlower = IntVar()
Entry(intwindow, textvariable = getlower).grid(row=2, column=1)

bty = Button(intwindow, text='click', command = lambda: newfunction()).grid(row=3)

def newfunction():
    x69 = get1.get()
    x_upper = getupper.get()
    x_lower = getlower.get()

    testz = int(x69)
    upperz= int(x_upper)
    lowerz = int(x_lower)



    x9 = lambda x: x69
    res = integrate.quad(x9, x_lower,x_upper)        

    randomwindow = Tk()
    label = Label(randomwindow, text = 'you got {} '.format(round(res[0])))
    label.grid(row=1)

   # Label(randomwindow, text = 'you got %s ' % res).grid(row=1)
    randomwindow.mainloop()



mainloop()
newtest1()

如果你看看函数 newfunction() 里面有代码

    x9 = lambda x: x69
    res = integrate.quad(x9, x_lower,x_upper)

我希望在弹出框中,我可以输入诸如 2*x 之类的内容,它会集成。但是以前我在测试时使用 get1 = IntVar() 来查看输入框中的数字是否有效。我尝试为我目前试图实现的目标删除它,但这会产生一些逻辑错误。为什么我不能在弹出框中输入我自己的函数以x的形式让python集成呢?

编辑


@furas 这是我现在使用的代码

import numpy
from numpy import *
import scipy.integrate as integrate
import scipy.special as special
from tkinter import *



def newtest1():
intwindow = Tk()

Label(intwindow, text = 'enter here', font = ('Symbol')).grid(row=0)
Label(intwindow, text = 'enter upper bound', font = ('Symbol')).grid(row=1)
Label(intwindow, text = 'enter lower bound', font = ('Symbol')).grid(row=2)

get1 = StringVar()
Entry(intwindow, textvariable = get1).grid(row=0, column=1)

getupper = IntVar()
Entry(intwindow, textvariable = getupper).grid(row=1, column=1)

getlower = IntVar()
Entry(intwindow, textvariable = getlower).grid(row=2, column=1)

bty = Button(intwindow, text='click', command = lambda: newfunction()).grid(row=3)

def newfunction():
    x69 = get1.get()
    x_upper = getupper.get()
    x_lower = getlower.get()

    #testz = int(x69)
    upperz= int(x_upper)
    lowerz = int(x_lower)



    x9 = eval(f"lambda x: {x69}")
    res = integrate.quad(x9, x_lower,x_upper)        

    randomwindow = Tk()
    label = Label(randomwindow, text = 'you got {} '.format(round(res[0])))
    label.grid(row=1)

   # Label(randomwindow, text = 'you got %s ' % res).grid(row=1)
    randomwindow.mainloop()



mainloop()
newtest1()

这是我得到的错误

Exception in Tkinter callback
Traceback (most recent call last):
  File "/opt/anaconda3/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
    return self.func(*args)
  File "/Users/isa/Desktop/Diff Eqns/diffeqn.py", line 45, in <lambda>
    bty = Button(intwindow, text='click', command = lambda: newfunction()).grid(row=3)
  File "/Users/isa/Desktop/Diff Eqns/diffeqn.py", line 58, in newfunction
    x9 = eval(lambda x: {x69})
TypeError: eval() arg 1 must be a string, bytes or code object

标签: pythontkinterintegration

解决方案


如果要放入字符串"2*x"Entry则必须使用StringVar()而不是IntVar()获取它。

并且您需要使用eval()将此字符串转换为可以计算值的函数

x9 = lambda x: eval(x69)

或使用 f-string 或.format()将此字符串放在其他字符串中

x9 = eval(f"lambad x: {x69}")
x9 = eval("lambad x: {}".format(x69)")

在下面的代码中,我使用了名称,这意味着一些东西,所以它看起来像

function = lambda x: eval(function_str)

在代码中,我还添加了其他更改——主要与PEP 8 相关——Python 代码样式指南

import scipy.integrate as integrate
import tkinter as tk # PEP8: `import *` is not preferred

# --- functions ---

def newtest1():

    # - subfunctions -

    def on_button_click(): # PEP8: name of function should means something
        function_str = function_var.get() # PEP8: name of variable should means something
        upper_int = upper_var.get()
        lower_int = lower_var.get()

        function = lambda x: eval(function_str)
        #function = eval(f"lambda x: {function_str}")
        result = integrate.quad(function, lower_int, upper_int)        
        result = round(result[0])

        randomwindow = tk.Toplevel() # second windows should use `Toplevel()` without `mainloop
        label = tk.Label(randomwindow, text=' you got {} '.format(result))
        label.grid(row=1)

        #tk.Label(randomwindow, text=' you got %s ' % result).grid(row=1)

    # - main -

    intwindow = tk.Tk()

    options = {'font': 'Symbol'}
    tk.Label(intwindow, text='enter here', **options).grid(row=0)  # PEP8: without spaces around '='
    tk.Label(intwindow, text='enter upper bound', **options).grid(row=1)
    tk.Label(intwindow, text='enter lower bound', **options).grid(row=2)

    function_var = tk.StringVar() # PEP8: name of variable should means something
    tk.Entry(intwindow, textvariable=function_var).grid(row=0, column=1)

    upper_var = tk.IntVar()
    tk.Entry(intwindow, textvariable=upper_var).grid(row=1, column=1)

    lower_var = tk.IntVar()
    tk.Entry(intwindow, textvariable=lower_var).grid(row=2, column=1)

    tk.Button(intwindow, text='click', command=on_button_click).grid(row=3) # you don't need `lambda` when function created at start

    intwindow.mainloop()

# --- main ---

newtest1()

推荐阅读