4
import
matplotlib.pyplot as plt
5
from
matplotlib.pylab
import
mpl
6
from
matplotlib.backends.backend_tkagg
import
FigureCanvasTkAgg, NavigationToolbar2Tk
7
import
tkinter as tk
8
import
numpy as np
9
import
time,sys
10
import
threading
12
mpl.rcParams[
'
font.sans-serif
'
] = [
'
SimHei
'
]
#
中文显示
13
mpl.rcParams[
'
axes.unicode_minus
'
] = False
#
负号显示
15
global
win
16
global
tempGraphLabel, tempData, runFlag
17
runFlag =
True
18
tempData =
[]
20
'''
21
图表类,定义时参数root为父控件
22
'''
23
class
tempGraph():
24
def
__init__
(self, root):
25
self.root = root
#
主窗体
26
self.canvas = tk.Canvas()
#
创建一块显示图形的画布
27
self.figure = self.create_matplotlib()
#
返回matplotlib所画图形的figure对象
28
self.showGraphIn(self.figure)
#
将figure显示在tkinter窗体上面
30
'''
生成fig
'''
31
def
create_matplotlib(self):
32
#
创建绘图对象f
33
f = plt.figure(num=2, figsize=(16, 8), dpi=100, edgecolor=
'
green
'
, frameon=
True)
34
#
创建一副子图
35
self.fig11 = plt.subplot(1, 1, 1
)
36
self.line11, =
self.fig11.plot([], [])
38
def
setLabel(fig, title, titleColor=
"
red
"
):
39
fig.set_title(title+
"
温度曲线
"
, color=titleColor)
#
设置标题
40
fig.set_xlabel(
'
时间[s]
'
)
#
设置x轴标签
41
fig.set_ylabel(
"
温度[℃]
"
)
#
设置y轴标签
42
setLabel(self.fig11,
"
设备1
"
)
43
#
fig1.set_yticks([-1, -1 / 2, 0, 1 / 2, 1]) # 设置坐标轴刻度
44
f.tight_layout()
#
自动紧凑布局
45
return
f
47
'''
把fig显示到tkinter
'''
48
def
showGraphIn(self, figure):
49
#
把绘制的图形显示到tkinter窗口上
50
self.canvas =
FigureCanvasTkAgg(figure, self.root)
51
self.canvas.draw()
#
以前的版本使用show()方法,matplotlib 2.2之后不再推荐show()用draw代替,但是用show不会报错,会显示警告
52
self.canvas.get_tk_widget().pack(side=tk.TOP)
#
, fill=tk.BOTH, expand=1
54
#
把matplotlib绘制图形的导航工具栏显示到tkinter窗口上
55
toolbar =
NavigationToolbar2Tk(self.canvas,
56
self.root)
#
matplotlib 2.2版本之后推荐使用NavigationToolbar2Tk,若使用NavigationToolbar2TkAgg会警告
57
toolbar.update()
58
self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1
)
60
'''
更新fig
'''
61
def
updateMeltGraph(self, meltData):
62
x = [i
for
i
in
range(len(meltData))]
63
self.line11.set_xdata(x)
#
x轴也必须更新
64
self.line11.set_ydata(meltData)
#
更新y轴数据
65
#
更新x数据,但未更新绘图范围。当我把新数据放在绘图上时,它完全超出了范围。解决办法是增加:
66
self.fig11.relim()
67
self.fig11.autoscale_view()
68
plt.draw()
69
#
self.canvas.draw_idle()
70
'''
71
更新数据,在次线程中运行
72
'''
73
def
updataData():
74
global
tempData,runFlag
75
while
runFlag:
76
tempData.append(5
)
77
time.sleep(1
)
78
'''
79
更新窗口
80
'''
81
def
updateWindow():
82
global
win
83
global
tempGraphLabel, tempData, runFlag
84
if
runFlag:
85
tempGraphLabel.updateMeltGraph(tempData)
86
win.after(1000, updateWindow)
#
1000ms更新画布
87
'''
88
关闭窗口触发函数,关闭S7连接,置位flag
89
'''
90
def
closeWindow():
91
global
runFlag
92
runFlag =
False
93
sys.exit()
94
'''
95
创建控件
96
'''
97
def
createGUI():
98
global
win
99
win =
tk.Tk()
100
displayWidth = win.winfo_screenwidth()
#
获取屏幕宽度
101
displayHeight =
win.winfo_screenheight()
102
winWidth, winHeight = displayWidth, displayHeight - 70
103
winX, winY = -8
, 0
104
#
winX, winY = int((displayWidth - winWidth) /
105
#
2), int((displayHeight - winHeight - 70) / 2)
106
win.title(
"
窗口标题
"
)
107
win.geometry(
108
'
%dx%d-%d+%d
'
%
109
(winWidth,
110
winHeight,
111
winX, winY))
#
%dx%d宽度x 高度+横向偏移量(距左边)+纵向偏移量(距上边)
112
#
win.resizable(0, 0) # 不使能最大化
113
win.protocol(
"
WM_DELETE_WINDOW
"
, closeWindow)
114
#
win.iconbitmap(r'resource/images/motor.ico') # 窗口图标
116
graphFrame = tk.Frame(win)
#
创建图表控件
117
graphFrame.place(x=0, y=
0)
118
global
tempGraphLabel
119
tempGraphLabel =
tempGraph(graphFrame)
121
recv_data = threading.Thread(target=updataData)
#
开启线程
122
recv_data.start()
124
updateWindow()
#
更新画布
125
win.mainloop()
127
if
__name__
==
'
__main__
'
:
128
createGUI()