Python+tkinter实现一个绘图风格控件
作者:微小冷
这篇文章主要为大家详细介绍了Python如何利用tkinter实现一个简单的绘图风格控件,文中的示例代码讲解详细,感兴趣的小伙伴可以学习一下
Python绘图系统:
绘图风格
以plot为例,下面列出常用参数,其中枚举类型表示有有限个可选择的值,说明适用于Combobox控件。
参数 | 类型 | 功能 |
---|---|---|
linestyle | 枚举 | 线条类型 |
linewidth | 小数 | 线条宽度 |
color | 字符串 | 颜色 |
marker | 枚举 | 散点形状 |
markersize | 小数 | 指定点的大小。 |
markeredgecolor | 字符串 | 点的边框色 |
label | 字符串 | 图例标签 |
alpha | 小数 | 透明度 |
zorder | 整数 | 所在绘图层 |
为了便于调用,可以将这些参数封装为字典
def initConst(self): self.VAR_LABS = { "线型" : "linestyle", "线宽" : "linewidth", "线色" : "color", "点型" : "marker" , "点径" : "markersize", "点色" : "markeredgecolor", "标签" : "label" , "透明度" : "alpha", "层号" : "zorder" } self.STR_KEYS = ["标签"] self.COM_KEYS = ["线型", "点型"] self.NUM_KEYS = ["线宽", "点径", "透明度"] self.INT_KEYS = ["层号"] self.CLR_KEYS = ["线色", "点色"]
这样一来,初始化StringVar就方便很多
def initVars(self): self.varDct = {key:tk.StringVar() for key in self.VAR_LABS}
但接下来才是重头戏,UI绘制。
线型和点型
matplotlib中有四种线型,分别实现、虚线、点划线和点线,分别记作’-‘, ‘–’, ‘-.’, ‘:’;点型相对较多,标志有这些:’.‘, ‘,’, ‘1’, ‘2’, ‘3’, ‘4’, ‘+’, ‘x’, ‘|’, ‘_’, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ‘o’, ‘v’, ‘^’, ‘<’, ‘>’, ‘8’, ‘s’, ‘p’, ‘*’, ‘h’, ‘H’, ‘D’, ‘d’, ‘P’, ‘X’。
而点和线的设置均包含形状、尺寸以及颜色,基于这种对偶关系,可以将这些参数设成下列形式
def initLineMarker(self): enumDct = { "点型" : ['.', ',', '1', '2', '3', '4', '+', 'x', '|', '_', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 'o', 'v', '^', '<', '>', '8', 's', 'p', '*', 'h', 'H', 'D', 'd', 'P', 'X'], "线型" : ['-', '--', '-.', ':'] } frm = self.newFrame() for i in range(2): key = self.COM_KEYS[i] ttk.Label(frm, text=key).grid(row=i, column=0, padx=2) tmp = ttk.Combobox(frm, width=10, textvariable=self.varDct[key]) tmp.grid(row=i, column=1, padx=2, pady=2) tmp['value'] = enumDct[key] key = self.NUM_KEYS[i] ttk.Label(frm, text=key).grid(row=i, column=2, padx=2) tmp = ttk.Entry(frm, width=10, textvariable=self.varDct[key]) tmp.grid(row=i, column=3, padx=2, pady=2) key = self.CLR_KEYS[i] ttk.Label(frm, text=key).grid(row=i, column=4, padx=2) tmp = ttk.Entry(frm, width=10, textvariable=self.varDct[key]) tmp.grid(row=i, column=5, padx=2, pady=2)
其他参数
这样一来就只剩下标签,层号和透明度这三个参数了,由于标签颇有标题的意味,所以把这三个参数放在线型上面。
由于这些都是Entry和Label的组合,没什么值得说的,反正最后也要附上源代码,所以就从略了。
最后得到
源代码
目前整个项目的代码已经400多行,如果全粘在下面可读性比较差,故只把DrawStyle类的实现放在下面。完整代码可参考前几篇博客。
class DrawStyle(ttk.Frame): def __init__(self, master, varDct={}, ws=None, func=None, **options): super().__init__(master, **options) self.pack() self.initConst() self.initVars() self.initWidgets() def initConst(self): self.VAR_LABS = { "线型" : "linestyle", "线宽" : "linewidth", "线色" : "color", "点型" : "marker" , "点径" : "markersize", "点色" : "markeredgecolor", "标签" : "label" , "透明度" : "alpha", "层号" : "zorder" } self.STR_KEYS = ["标签"] self.COM_KEYS = ["线型", "点型"] self.NUM_KEYS = ["线宽", "点径", "透明度"] self.INT_KEYS = ["层号"] self.CLR_KEYS = ["线色", "点色"] def initVars(self): self.varDct = {key:tk.StringVar() for key in self.VAR_LABS} def newFrame(self): frm = ttk.Frame(self) frm.pack(side=tk.TOP, fill=tk.X) return frm def initWidgets(self): frm = self.newFrame() for i,key in enumerate(["标签", "层号", "透明度"]): tk.Label(frm, text=key).grid(row=0, column=i*2, padx=2) tmp = ttk.Entry(frm, width=10, textvariable=self.varDct[key]) tmp.grid(row=0, column=i*2+1, padx=2, pady=2) self.initLineMarker(frm) def initLineMarker(self, frm): enumDct = { "点型" : ['.', ',', '1', '2', '3', '4', '+', 'x', '|', '_', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 'o', 'v', '^', '<', '>', '8', 's', 'p', '*', 'h', 'H', 'D', 'd', 'P', 'X'], "线型" : ['-', '--', '-.', ':'] } for i in range(2): key = self.COM_KEYS[i] ttk.Label(frm, text=key).grid(row=i+1, column=0, padx=2) tmp = ttk.Combobox(frm, width=10, textvariable=self.varDct[key]) tmp.grid(row=i+1, column=1, padx=2, pady=2) tmp['value'] = enumDct[key] key = self.NUM_KEYS[i] ttk.Label(frm, text=key).grid(row=i+1, column=2, padx=2) tmp = ttk.Entry(frm, width=10, textvariable=self.varDct[key]) tmp.grid(row=i+1, column=3, padx=2, pady=2) key = self.CLR_KEYS[i] ttk.Label(frm, text=key).grid(row=i+1, column=4, padx=2) tmp = ttk.Entry(frm, width=10, textvariable=self.varDct[key]) tmp.grid(row=i+1, column=5, padx=2, pady=2) def getOneVar(self, key): v = self.varDct[key].get() if key in NUM_KEYS: return float(v) elif key in INT_KEYS: return int(v) else: return v def getVarDct(self): return {self.VAR_LABS[key] : self.varDct[key].get() for key in self.varDct}
以上就是Python+tkinter实现一个绘图风格控件的详细内容,更多关于Python tkinter的资料请关注脚本之家其它相关文章