Python_数学绘图工具MathToolsPaint[项目](动态组件与PaneWindow)(tkinter实现)【2022-01-17】
【v1.0.0版本】功能有限,但整体雏形框架已经搭好。实现时间:2天。
【注】 数学绘图工具–MathToolsPaint,版本Version 1.0.0。
【注1】将 Matploylib和turtle的绘制嵌入到tkinter的canvas中。
【注2】实现了 组件的动态生成显示与销毁。
【注3】具有 PaneWindow面板,更具实用性。
【注4】项目也会放在博主的Gitee仓库中。
【销毁组件实现思路】在pane上放上一个frame,在此frame上放canvas和其他组件,直接销毁frame即可。
1.MathToolsPaint.py
from math import *
import tkinter as tk
from turtle import RawTurtle
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
matplotlib.use('TkAgg')
f = plt.Figure(figsize=(2.55, 2.55), dpi=160)
fmplot = f.add_subplot(111)
password = '123456'
def newwindow():
nwin = tk.Tk()
nwin.title("激活软件")
nwin.geometry("450x250+300+300")
lb1 = tk.Label(nwin,text="输入激活码")
lb1.pack()
en1 = tk.Entry(nwin)
en1.pack()
bt1 = tk.Button(nwin,text='确认')
bt1.pack()
def on_closing():
if tk.messagebox.askokcancel("Quit", "Do you want to quit?"):
nwin.destroy()
nwin.protocol("WM_DELETE_WINDOW", on_closing)
nwin.mainloop()
def mt():
s = e1.get()
x = np.linspace(-40, 40, 2000)
x = list(x)
y = []
xx = []
ss = ""
i = 0
for i in x:
ss = ""
for c in s:
if c == 'x':
ss = ss + str(i)
else:
ss = ss + c
try:
yy = eval(ss)
except:
continue
res = "f(x) = "+s+"\ny = \n"+str(yy)
left.config(text=res)
xx.append(i)
y.append(yy)
fmplot.cla()
fmplot.grid()
fmplot.plot(xx,y,2)
canvs.draw()
def tmt():
s = te1.get()
if s == "":
return
x = np.linspace(-20, 20, 1000)
x = list(x)
y = []
xx = []
ss = ""
i = 0
for i in x:
ss = ""
for c in s:
if c == 'x':
ss = ss + str(i)
else:
ss = ss + c
try:
yy = eval(ss)
except:
continue
xx.append(i)
y.append(yy)
turtle.clear()
turtle.pensize(2)
turtle.pencolor("red")
print(len(xx),len(y))
print(xx,"\n",y)
j = 0
while j < len(y):
if j == 0:
turtle.penup()
turtle.goto(xx[j],y[j]-50)
res = "y = \n"+str(y[j])
left.config(text=res)
j = j + 1
turtle.pendown()
else:
turtle.goto(xx[j],y[j]-50)
res = "y = \n"+str(y[j])
left.config(text=res)
j = j + 1
'''能运行,但绘图结果有问题'''
def init_tkwindow():
tfmt = []
fmt = []
def addfm():
fm1 = tk.Frame(p3)
fmt.append(fm1)
p3.add(fm1)
global e1
e1 = tk.Entry(fm1,width=300,background='yellow',borderwidth=2,fg="blue",font="黑体")
e1.pack()
global canvs
canvs = FigureCanvasTkAgg(f, fm1)
canvs.draw()
canvs.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
def addtfm():
tfm1 = tk.Frame(p3)
tfmt.append(tfm1)
p3.add(tfm1)
global te1
te1 = tk.Entry(tfm1,width=300,background='yellow',borderwidth=2,fg="blue",font="黑体")
te1.pack()
canvs = tk.Canvas(tfm1)
canvs.pack(fill=tk.BOTH, expand=1)
global turtle
turtle = RawTurtle(canvs)
def CardioidLine():
turtle.clear()
i = 0
turtle.speed(5)
turtle.pencolor("green")
turtle.pensize(3)
while (i <= 2 * 3.1415926):
p = 80 * (1 - cos(i))
x = p * cos(i)
y = p * sin(i)
if i == 0:
turtle.penup()
turtle.goto(x+120, y-120)
res = "y = \n" + str(y)
left.config(text=res)
turtle.pendown()
else:
turtle.goto(x + 120, y - 120)
res = "y = \n" + str(y)
left.config(text=res)
i = i + 0.01
def UnQuaEqu():
turtle.clear()
turtle.speed(0)
turtle.pencolor("green")
turtle.pensize(3)
i = -70
while (i <= 110):
if i == -70:
turtle.penup()
y = 0.02 * (i - 20) * (i - 20) + 50
turtle.goto(i + 200, y - 300)
i = i + 0.1
res = "y = \n" + str(y)
left.config(text=res)
turtle.pendown()
else:
i = i + 0.1
y = 0.02 * (i - 20) * (i - 20) + 50
res = "y = \n" + str(y)
left.config(text=res)
turtle.goto(i+200, y-300)
turtle.penup()
turtle.goto(200, -300)
turtle.pendown()
turtle.seth(90)
turtle.fd(230)
turtle.seth(-70)
turtle.fd(15)
turtle.penup()
turtle.goto(200, -70)
turtle.pendown()
turtle.seth(-110)
turtle.fd(15)
turtle.penup()
turtle.goto(200, 535)
turtle.pendown()
turtle.write("y", True, align="center")
turtle.penup()
turtle.goto(200, -300)
turtle.pendown()
turtle.seth(-90)
turtle.fd(90)
turtle.penup()
turtle.goto(200, -300)
turtle.pendown()
turtle.seth(0)
turtle.fd(150)
turtle.seth(-160)
turtle.fd(15)
turtle.penup()
turtle.goto(350, -300)
turtle.pendown()
turtle.seth(160)
turtle.fd(15)
turtle.penup()
turtle.goto(360, -300)
turtle.pendown()
turtle.write("x", True, align="center")
turtle.penup()
turtle.goto(200, -300)
turtle.pendown()
turtle.seth(-180)
turtle.fd(150)
turtle.penup()
turtle.goto(200, -420)
turtle.write("一元二次方程图像:y = 0.02*(x-20)^2+50", True, align="center")
turtle.goto(200, -600)
def SinDot():
turtle.clear()
turtle.speed(0)
turtle.pencolor("green")
turtle.pensize(3)
i = -130
while (i <= 130):
if i == -130:
turtle.penup()
y = 60 * sin(0.06 * i + 0.5) + 20
turtle.goto(i+200, y-200)
res = "y = \n" + str(y)
left.config(text=res)
i = i + 0.1
turtle.pendown()
else:
i = i + 0.1
y = 60 * sin(0.06 * i + 0.5) + 20
res = "y = \n" + str(y)
left.config(text=res)
turtle.goto(i+200, y-200)
turtle.penup()
turtle.goto(200, -200)
turtle.pendown()
turtle.seth(90)
turtle.fd(230)
turtle.seth(-70)
turtle.fd(15)
turtle.penup()
turtle.goto(200, 30)
turtle.pendown()
turtle.seth(-110)
turtle.fd(15)
turtle.penup()
turtle.goto(200, -200)
turtle.pendown()
turtle.seth(-90)
turtle.fd(90)
turtle.penup()
turtle.goto(200, -200)
turtle.pendown()
turtle.seth(0)
turtle.fd(150)
turtle.seth(-160)
turtle.fd(15)
turtle.penup()
turtle.goto(350, -200)
turtle.pendown()
turtle.seth(160)
turtle.fd(15)
turtle.penup()
turtle.goto(200, -200)
turtle.pendown()
turtle.seth(-180)
turtle.fd(150)
turtle.penup()
turtle.goto(200, -300)
turtle.write("正弦函数方程图像:y = 60*math.sin(0.06*i+0.5)+20", True, align="center")
turtle.goto(200, -300)
def LineToFaceCos():
turtle.clear()
turtle.speed(0)
turtle.pensize(2)
turtle.pencolor("blue")
col = ["blue", "green"]
def subline(x, coll, y=[]):
turtle.pencolor(coll)
turtle.penup()
turtle.goto(x, -320)
res = "x = \n" + str(x)
left.config(text=res)
turtle.pendown()
for i in y:
left.config(text=res)
turtle.goto(x, i-200 - 2)
turtle.penup()
turtle.goto(x, i-200 + 2)
turtle.pendown()
turtle.goto(x, 30)
k = 0
i = -150
while (i <= 150):
if k == 2:
k = 0
i = i + 1
y = []
y.append(70 * cos(0.06 * i + 4) + 20)
subline(i+200, col[k], y)
k = k + 1
def LineToFaceCircle():
turtle.clear()
turtle.speed(0)
turtle.pensize(2)
turtle.pencolor("blue")
col = ["yellow"]
def subline(x, coll, y=[]):
turtle.pencolor(coll)
turtle.penup()
res = "x = \n" + str(x)
left.config(text=res)
turtle.goto(x, -300)
turtle.pendown()
for i in y:
if x >= -150+200 and x < -60+200:
turtle.goto(x, i-100 - 1.4)
# tle.penup()
turtle.pencolor("red")
turtle.goto(x, i-100 + 1.4)
turtle.pencolor(coll)
# tle.pendown()
elif x >= -60+200 and x <= 0+200:
turtle.goto(x, i-100 - 0.8)
# tle.penup()
turtle.pencolor("red")
turtle.goto(x, i-100 + 0.8)
turtle.pencolor(coll)
# tle.pendown()
if x > 0+200 and x <= 60+200:
turtle.goto(x, i-100 - 0.8)
# tle.penup()
turtle.pencolor("red")
turtle.goto(x, i-100 + 0.8)
turtle.pencolor(coll)
# tle.pendown()
elif x >= 60+200 and x <= 150+200:
turtle.goto(x, i-100 - 1.4)
# tle.penup()
turtle.pencolor("red")
turtle.goto(x, i-100 + 1.4)
turtle.pencolor(coll)
# tle.pendown()
turtle.goto(x, 120)
k = 0
i = -150
while (i <= 150):
if k == 1:
k = 0
y = []
if i == 150 or i == -150:
y.append(sqrt(22500 - i * i))
else:
y.append(-sqrt(22500 - i * i))
y.append(sqrt(22500 - i * i))
subline(i+200, col[k], y)
i = i + 1
k = k + 1
def LineToFaceTuoCircle():
turtle.clear()
turtle.speed(0)
turtle.pensize(2)
turtle.pencolor("blue")
col = ["gold"]
def subline(x, coll, y=[]):
turtle.pencolor(coll)
turtle.penup()
res = "x = \n" + str(x)
left.config(text=res)
turtle.goto(x, -200)
turtle.pendown()
for i in y:
if x >= -150+200 and x < -60+200:
turtle.goto(x, i-100 - 1.4)
# tle.penup()
turtle.pencolor("red")
turtle.goto(x, i-100 + 1.4)
turtle.pencolor(coll)
# tle.pendown()
elif x >= -60+200 and x <= 0+200:
turtle.goto(x, i-100 - 0.8)
# tle.penup()
turtle.pencolor("yellow")
turtle.goto(x, i-100 + 0.8)
turtle.pencolor(coll)
# tle.pendown()
if x > 0+200 and x <= 60+200:
turtle.goto(x, i-100 - 0.8)
# tle.penup()
turtle.pencolor("orange")
turtle.goto(x, i-100 + 0.8)
turtle.pencolor(coll)
# tle.pendown()
elif x >= 60+200 and x <= 150+200:
turtle.goto(x, i-100 - 1.4)
# tle.penup()
turtle.pencolor("skyblue")
turtle.goto(x, i-100 + 1.4)
turtle.pencolor(coll)
# tle.pendown()
turtle.goto(x, 15)
k = 0
i = -150
while (i <= 150):
if k == 1:
k = 0
y = []
if i == 150 or i == -150:
y.append(sqrt(2500 - i * i * (1 / 9)))
else:
y.append(-sqrt(2500 - i * i * (1 / 9)))
y.append(sqrt(2500 - i * i * (1 / 9)))
subline(i+200, col[k], y)
i = i + 1
k = k + 1
def FaceToVolume():
def turtleSet():
turtle.speed(0)
turtle.pensize(2)
turtle.pencolor("blue")
def CreateXYZ():
turtle.pencolor("black")
turtle.penup()
turtle.goto(200, -200)
turtle.seth(0)
turtle.pendown()
turtle.goto(400, -200)
turtle.seth(135)
turtle.fd(10)
turtle.penup()
turtle.goto(400, -200)
turtle.pendown()
turtle.seth(-135)
turtle.fd(10)
turtle.penup()
turtle.goto(403, -200)
turtle.write("x(X)", font=("宋体", 16, "normal"))
turtle.penup()
turtle.goto(200, -200)
turtle.seth(0)
turtle.pendown()
turtle.goto(-60, -200)
turtle.penup()
turtle.goto(200, -200)
turtle.seth(45)
turtle.pendown()
turtle.fd(210)
turtle.penup()
turtle.fd(3)
turtle.write("y", font=("宋体", 16, "normal"))
turtle.bk(3)
turtle.pendown()
turtle.seth(-180)
turtle.fd(10)
turtle.penup()
turtle.bk(10)
turtle.pendown()
turtle.seth(-90)
turtle.fd(10)
turtle.penup()
turtle.bk(10)
turtle.penup()
turtle.goto(200, -200)
turtle.seth(-135)
turtle.pendown()
turtle.fd(200)
turtle.penup()
turtle.goto(200, -200)
turtle.seth(90)
turtle.pendown()
turtle.fd(200)
turtle.penup()
turtle.fd(3)
turtle.write("z(Y)", font=("宋体", 16, "normal"))
turtle.pendown()
turtle.seth(-135)
turtle.fd(10)
turtle.penup()
turtle.bk(10)
turtle.pendown()
turtle.seth(-45)
turtle.fd(10)
turtle.penup()
turtle.bk(10)
turtle.penup()
turtle.goto(200, -200)
turtle.seth(-90)
turtle.pendown()
turtle.fd(200)
turtle.penup()
def subline(x, coll, z, y=[]):
turtle.pencolor(coll)
turtle.penup()
for y0 in y:
res = "x = \n" + str(x)+"\ny = \n"+str(y0)+"\nz = "+str(z)
left.config(text=res)
if fabs(y0 - z) <= 0.0001:
# print("OK",x,y0,z)
turtle.goto(x, 0 + z)
turtle.pendown()
turtle.dot(1)
turtle.penup()
else:
turtle.goto(x, 0 + z)
turtle.pendown()
turtle.seth(45)
turtle.fd(y0 / 2)
turtle.bk(y0)
turtle.penup()
def subface(z, coll):
k = 0
i = -150
while (i <= 150):
if k == 1:
k = 0
y = []
y.append(sqrt(2500 - i * i * (1 / 9)))
subline(i+200, coll, z-200, y)
i = i + 1
k = k + 1
def CreateV():
z = -50
col = ["blue", "green", "orange"]
k = 0
while z <= 50:
if k == 3:
k = 0
if z == -50 or z == 50:
subface(z, "green")
else:
subface(z, col[k])
z = z + 2
k = k + 1
turtle.clear()
turtleSet()
CreateXYZ()
CreateV()
CreateXYZ()
def delfm():
if len(fmt) != 0:
fmt[0].destroy()
fmt.pop(0)
if len(tfmt) != 0:
tfmt[0].destroy()
tfmt.pop(0)
left.config(text="")
global rootwindow
rootwindow = tk.Tk()
rootwindow.title("MathToolsPaint [Version 1.0.0]")
rootwindow.geometry("750x700+300+200")
p = tk.PanedWindow(orient=tk.HORIZONTAL,showhandle = False,sashrelief=tk.RAISED)
p.pack(fill=tk.BOTH,expand=1)
global left
left = tk.Label(p, text="[结果输出]")
p.add(left)
p2 = tk.PanedWindow(orient=tk.VERTICAL,showhandle = False,sashrelief=tk.RAISED)
p.add(p2)
global fm0
fm0 = tk.Frame(p2)
p2.add(fm0)
global status
status = []
status.append(False)
status.append(False)
status.append(False)
def openToolbartext():
global tempfam
tempfam = tk.Frame(fm0)
tempfam.pack(fill=tk.BOTH, expand=1)
global templabel
templabel = tk.Label(tempfam,text='工具栏位置')
templabel.pack(fill=tk.BOTH,expand=1)
status[0] = True
openToolbartext()
def openMpltBar():
if status[1] == False:
try:
tempfam.destroy()
except:
pass
status[0] = False
status[1] = True
global fmtemp
fmtemp = tk.Frame(fm0)
fmtemp.pack(fill=tk.BOTH,expand=1)
b1 = tk.Button(fmtemp, text='生成求解区域', command=addfm)
b1.pack(side='left')
b2 = tk.Button(fmtemp, text='解除求解区域', command=delfm)
b2.pack(side='left')
b3 = tk.Button(fmtemp, text='[MatPlotLibGo]', command=mt)
b3.pack(side='left')
def openTulrBar():
if status[2] == False:
try:
tempfam.destroy()
except:
pass
status[0] = False
status[2] = True
global tfmtemp
tfmtemp = tk.Frame(fm0)
tfmtemp.pack(fill=tk.BOTH,expand=1)
bb1= tk.Button(tfmtemp, text='turtle求解区域', command=addtfm)
bb1.pack(side='left')
bb2 = tk.Button(tfmtemp, text='解除求解区域', command=delfm)
bb2.pack(side='left')
bbgo = tk.Button(tfmtemp, text='[TurtelGo]', command=tmt)
bbgo.pack(side='left',padx=1)
bb3 = tk.Button(tfmtemp, text='心形线', command=CardioidLine)
bb3.pack(side='left')
bb4 = tk.Button(tfmtemp, text='一元二次函数', command=UnQuaEqu)
bb4.pack(side='left')
bb5 = tk.Button(tfmtemp, text='正弦函数', command=SinDot)
bb5.pack(side='left')
bb6 = tk.Button(tfmtemp, text='余弦函数', command=LineToFaceCos)
bb6.pack(side='left')
bb7 = tk.Button(tfmtemp, text='圆函数', command=LineToFaceCircle)
bb7.pack(side='left')
bb8 = tk.Button(tfmtemp, text='椭圆函数', command=LineToFaceTuoCircle)
bb8.pack(side='left')
bb9 = tk.Button(tfmtemp, text='椭圆柱体', command=FaceToVolume)
bb9.pack(side='left')
def closeMpltBar():
try:
fmtemp.destroy()
except:
pass
status[1] = False
if status[0] == False:
openToolbartext()
left.config(text="[结果输出]")
def closeTulrBar():
try:
tfmtemp.destroy()
except:
pass
status[2] = False
if status[0] == False:
openToolbartext()
left.config(text="[结果输出]")
p3 = tk.PanedWindow(orient=tk.HORIZONTAL, showhandle=False, sashrelief=tk.RAISED)
p2.add(p3)
menub = tk.Menu(rootwindow)
menu1 = tk.Menu(menub, tearoff=True,foreground='red')
menu2 = tk.Menu(menub, tearoff=True,foreground='orange')
menu3 = tk.Menu(menub, tearoff=True,foreground='purple')
menu4 = tk.Menu(menub, tearoff=True,foreground='blue')
menu5 = tk.Menu(menub, tearoff=True,bg='gold')
menub.add_cascade(label="初等函数",menu=menu1)
menub.add_cascade(label="Matplotlib绘制",menu=menu2)
menub.add_cascade(label="Turtle绘制",menu=menu3)
menub.add_cascade(label="帮助",menu=menu4)
menub.add_cascade(label="作者", menu=menu5)
menu1.add_command(label='待实现1',font=("黑体", 10))
menu1.add_command(label='待实现2',font=("黑体", 10))
menu2.add_command(label='开启MPLOT工具栏',font=("黑体", 10),command=openMpltBar)
menu2.add_command(label='关闭MPLOT工具栏',font=("黑体", 10),command=closeMpltBar)
menu3.add_command(label='开启TTLE具栏',font=("黑体", 10),command=openTulrBar)
menu3.add_command(label='关闭TTLE具栏',font=("黑体", 10),command=closeTulrBar)
menu4.add_command(label='使用说明',font=("黑体", 10))
menu4.add_command(label='激活软件',font=("黑体", 10),command=newwindow)
menu5.add_command(label='姓名:***')
menu5.add_command(label='CSDN:TDTX')
menu5.add_command(label='Gitee:TDTXYZHH')
rootwindow.config(menu = menub)
def on_closing():
if tk.messagebox.askokcancel("Quit", "Do you want to quit?"):
rootwindow.destroy()
rootwindow.protocol("WM_DELETE_WINDOW", on_closing)
try:
rootwindow.mainloop()
except:
pass
if __name__ == '__main__':
init_tkwindow()
2.界面截图
2.1 启动界面
2.2 PaneWindow调整
2.3 菜单栏展示
2.4 MatPlotlib绘制(将MatPlotlib嵌入tkinter的Canvas中)
- 点击“开启MPLOT工具栏”,在工具栏位置显示三个按钮
2.点击“生成求解区域”,会在下方生成Matplotlib的绘图区域与函数表达式输入框
3.输入一个表达式,点击“[MatPlotLibGo]”即可绘制出输入的函数
4.点击“解除求解区域”,则会销毁刚才生成的求解区域
5.点击“关闭MPLOT工具栏”,会销毁该功能工具栏
2.5 Turtle绘制(将Turtle嵌入tkinter的Canvas中)
【注】与MatPlotlib绘制功能用法一样,在此只展示几个运行图