Python绘图系统16:动态更新tkinter组件

编程入门 行业动态 更新时间:2024-10-13 00:31:10

Python绘图系统16:动态更新tkinter<a href=https://www.elefans.com/category/jswz/34/1771375.html style=组件"/>

Python绘图系统16:动态更新tkinter组件

文章目录

    • 前情提要
    • 源代码模式
    • 输入序列
    • 源码

Python绘图系统:

  • 📈从0开始的3D绘图系统📉一套3D坐标,多个函数📊散点图、极坐标和子图
  • 自定义控件:极坐标📉绘图风格📉风格控件
  • 图表类型和风格:定制绘图风格
  • 坐标设置进阶:动态更新组件

前情提要

AxisFrame是存放某一维坐标的组件,目前由一个标签,一个下拉选框和一个输入框构成。下拉选框主要目的是判断输入方式,目前有4个选择,分别是源代码、序列化、外部导入和无数据。

其中源代码就是通过调用eval执行的代码,这个没什么好说的。但序列化目前的实现方式,用的仍旧是类似Pyton的语法,然后在外面套一层壳,这还是得程序员才能懂。而外部导入目前只起到一个说明的作用,即外部数据导入了,然后这个地方一变,换言之,AxisFrame自身并没有导入数据的功能。

所以,这两个功能还是需要优化的,当ComboBox的选中项发生变化时,需要调整一下布局,故而initWidgets函数改成下面的形式,其中initRes则根据传入的数据获取模式来初始化其他控件。

def initWidgets(self, widths):tk.Label(self, text=self.label, width=widths[0]).pack(side=tk.LEFT)slct = ttk.Combobox(self, width=widths[1], textvariable=self.mode)slct['value'] = self.MODESslct.bind('<<ComboboxSelected>>', self.slctChanged)slct.pack(side=tk.LEFT)self.initRes(widths[3])

源代码模式

源码模式最简单,只要有一个Entry就可以,从外观上来看,不需要做任何修改,但代码需要写到另一个函数中。

代码如下,其逻辑顺序是,先实现一个srcEntry,然后调用showSrcEntry将其展示出来。

def initRes(self, width):self.errWidth = widthmode = self.mode.get()self.srcEntry = tk.Entry(self, width=width, textvariable=self.srcText)if mode=="源代码":self.showSrcEntry()def showSrcEntry(self):self.srcEntry.pack(padx=5, pady=2, side=tk.LEFT, fill=tk.X)

其中self.srcText是一个StringVar,是在initVar中定义的

self.srcText = tk.StringVar()

然后把readPython函数改为

def readPython(self, t=None, x=None, y=None, z=None):self.data = eval(self.srcText.get())return self.data

输入序列

序列化的含义是生成一个等差数列,要有起点,有终点,还得有步长。所以最直接的创建方法,就是三个Label和三个Entry,而且这些部件需要放进一个Frame中。结合已有的源代码输入控件,initRes函数改为下列形式。

def initRes(self, width):self.errWidth = widthself.srcEntry = tk.Entry(self, width=width, textvariable=self.srcText)self.arrFrame = ttk.Frame(self, width=width-5)for i, key in enumerate(["起点", "终点", "步长"]):tk.Label(self.arrFrame, text=key).grid(row=0, column=i*3)tk.Entry(self.arrFrame, width=int(width/6), textvariable=self.arrText[i]).grid(row=0, column=i*3+1)                self.showRes(self.mode.get())

其中self.arrText是一个StringVar列表,定义在initVar中

self.arrText = [tk.StringVar() for _ in range(3)]

self.showRes则是显示某组部件的方法

def showRes(self, mode):resDct = {"源代码":self.srcEntry, "序列化":self.arrFrame}resDct[mode].pack(padx=5, pady=2, side=tk.LEFT, fill=tk.X)

最后效果如下

另一方面,需要更改getArray函数

def getArray(self):vs = [float(t.get()) for t in self.arrText]self.data = np.arange(*vs)return self.data

绘图结果如下

源码

本文仅改动了aframe.py中的源代码,其他代码在这篇博客后面:定制风格的绘图系统

aframe.py改动之后的代码如下

import tkinter as tk
import tkinter.ttk as ttkimport numpy as npclass AxisFrame(ttk.Frame):# widths 是每个控件的宽度def __init__(self, master, label, mode, widths, **options):super().__init__(master, **options)self.pack()self.label = labelself.initVar(mode)self.initWidgets(widths)def initVar(self, mode):self.MODES = ("序列化", "源代码", "外部导入", "无数据")self.mode = tk.StringVar()self.srcText = tk.StringVar()self.arrText = [tk.StringVar() for _ in range(3)]self.setMode(mode)def initWidgets(self, widths):tk.Label(self, text=self.label, width=widths[0]).pack(side=tk.LEFT)slct = ttk.Combobox(self, width=widths[1], textvariable=self.mode)slct['value'] = self.MODESslct.bind('<<ComboboxSelected>>', self.slctChanged)slct.pack(side=tk.LEFT)self.initRes(widths[2])def initRes(self, width):self.errWidth = widthself.srcEntry = tk.Entry(self, width=width, textvariable=self.srcText)self.arrFrame = ttk.Frame(self, width=width-5)for i, key in enumerate(["起点", "终点", "步长"]):tk.Label(self.arrFrame, text=key).grid(row=0, column=i*3)tk.Entry(self.arrFrame, width=int(width/6), textvariable=self.arrText[i]).grid(row=0, column=i*3+1)                self.showRes(self.mode.get())def showRes(self, mode):resDct = {"源代码":self.srcEntry, "序列化":self.arrFrame}resDct[mode].pack(padx=5, pady=2, side=tk.LEFT, fill=tk.X)def showSrcEntry(self):self.srcEntry.pack(padx=5, pady=2, side=tk.LEFT, fill=tk.X)def showArrFrame(self):self.arrFrame.pack(padx=5, pady=2, side=tk.LEFT, fill=tk.X)def slctChanged(self, evt):self.srcEntry.pack_forget()self.arrFrame.pack_forget()mode = self.mode.get()self.showRes(self.mode.get())def setText(self, text):self.entry.delete(0, "end")self.entry.insert(0, text)def get(self):return self.entry.get()def setMode(self, mode):if type(mode) != str:mode = self.MODES[mode]self.mode.set(mode)def setData(self, data=None, **txyz):if self.mode.get() == "序列化":return self.getArray()elif self.mode.get() == "外部导入":return self.loadData(data)else:return self.readPython(**txyz)def readPython(self, t=None, x=None, y=None, z=None):self.data = eval(self.srcText.get())return self.datadef loadData(self, data):if type(data) != type(None):self.data = datareturn self.datadef getArray(self):vs = [float(t.get()) for t in self.arrText]self.data = np.arange(*vs)return self.data

更多推荐

Python绘图系统16:动态更新tkinter组件

本文发布于:2024-02-08 21:10:24,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1675083.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:组件   动态   系统   Python   tkinter

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!