Python_数学绘图工具MathToolsPaint[项目](动态组件与PaneWindow)(tkinter实现)


目录
  • 1.MathToolsPaint.py
  • 2.界面截图
    • 2.1 启动界面
    • 2.2 PaneWindow调整
    • 2.3 菜单栏展示
    • 2.4 MatPlotlib绘制(将MatPlotlib嵌入tkinter的Canvas中)
    • 2.5 Turtle绘制(将Turtle嵌入tkinter的Canvas中)
  • 3.软件功能展示(动态图)

【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中)

  1. 点击“开启MPLOT工具栏”,在工具栏位置显示三个按钮
    在这里插入图片描述
    2.点击“生成求解区域”,会在下方生成Matplotlib的绘图区域与函数表达式输入框
    在这里插入图片描述
    3.输入一个表达式,点击“[MatPlotLibGo]”即可绘制出输入的函数
    在这里插入图片描述
    4.点击“解除求解区域”,则会销毁刚才生成的求解区域
    在这里插入图片描述
    5.点击“关闭MPLOT工具栏”,会销毁该功能工具栏
    在这里插入图片描述

2.5 Turtle绘制(将Turtle嵌入tkinter的Canvas中)

【注】与MatPlotlib绘制功能用法一样,在此只展示几个运行图
在这里插入图片描述

3.软件功能展示(动态图)

在这里插入图片描述