1.思路
我们创建了一个继承自wx.Frame
的自定义窗口类MyFrame
。在MyFrame
的构造函数中,我们创建了一个matplotlib
的Figure
对象和一个FigureCanvas
对象,用于在窗口中显示绘图结果。然后,我们使用numpy
生成了一个包含100个点的x轴坐标数组self.x
和对应的正弦值数组。接下来,我们使用self.ax.plot
方法绘制了一条初始的正弦曲线,并保存了对这条曲线对象的引用self.line
。我们还创建了一个定时器self.timer
,并将其绑定到self.on_timer
方法上。self.on_timer
方法会在定时器触发时被调用,其中我们更新了x轴坐标数组和正弦曲线对象的数据,并重新绘制曲线。
2.运行效果
3.完整代码
import wx
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
class MyFrame(wx.Frame):
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, '动态正弦曲线', size=(600, 400))
self.panel = wx.Panel(self)
self.fig, self.ax = plt.subplots()
self.canvas = FigureCanvas(self.panel, -1, self.fig)
self.x = np.linspace(0, 2*np.pi, 100)
self.line, = self.ax.plot(self.x, np.sin(self.x))
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)
self.layout()
def layout(self):
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.canvas, 1, wx.EXPAND)
self.panel.SetSizer(sizer)
self.panel.Layout()
def on_timer(self, event):
self.x += 0.1
self.line.set_xdata(self.x)
self.ax.set_xlim(self.x.min(), self.x.max())
self.canvas.draw()
def start(self):
self.timer.Start(100)
if __name__ == '__main__':
app = wx.App()
frame = MyFrame(parent=None, id=-1)
frame.Show()
frame.start()
app.MainLoop()
4.知识点说明
在wxPython中,使用Sizer来管理窗口中的控件布局。调用panel的SetSizer方法可以将Sizer对象应用到panel上,从而实现控件的布局。
在代码中,调用self.panel.SetSizer(sizer)将sizer对象应用到self.panel上,然后调用self.panel.Layout()来重新计算并应用布局。
self.panel.Layout()的功能是重新计算并应用panel上的布局。当窗口大小发生变化时,可以调用该方法重新计算布局,从而保证控件的位置和大小能够随窗口的改变而自适应调整。
请注意,由于wxPython
和matplotlib
的事件循环机制不同,动态绘图时可能会出现卡顿或闪烁的情况。如果需要更流畅的动画效果,可以考虑使用其他库,如PyQtGraph
或Vispy
。