学习wxpython 15天用wxpython写一个多线程程序(第二篇)
解窗口分割和动态折线图绘制警告:本博客所写内容严禁盗用,违者必究!转发请标明出处\color{red}{警告:本博客所写内容严禁盗用,违者必究!转发请标明出处}警告:本博客所写内容严禁盗用,违者必究!转发请标明出处静态折线图绘制本功能模块参考如影随形的绘制正弦曲线,如影随形源代码如下下面代码引用如影随形《用wxpython 和numpy话画正弦曲线》#-*- coding: utf-8 -*-##
解窗口分割和动态折线图绘制
警 告 : 本 博 客 所 写 内 容 严 禁 盗 用 , 违 者 必 究 ! 转 发 请 标 明 出 处 \color{red}{警告:本博客所写内容严禁盗用,违者必究! 转发请标明出处} 警告:本博客所写内容严禁盗用,违者必究!转发请标明出处
静态折线图绘制
本功能模块参考如影随形的绘制正弦曲线,如影随形源代码如下
下面代码引用如影随形《用wxpython 和numpy话画正弦曲线》
#-*- coding: utf-8 -*-
################################################################################
## 使用wxPython的绘图模块wxPyPlot,需要数据可视化的时候,无需再借用其他的库或模块了
################################################################################
import numpy
import wx
import wx.lib.plot as wxPyPlot #导入绘图模块,并命名为wxPyPlot
#---------------------------------------------------------------------------
# 需要把数据封装进入MyDataObject中
def MyDataObject():
# 50 个点的sin函数,用蓝色圆点表示
data1 = 2.*numpy.pi*numpy.arange(100)/100.
data1.shape = (50, 2)
data1[:,1] = numpy.sin(data1[:,0])
markers = wxPyPlot.PolyMarker(data1, legend='Green Markers', colour='blue', marker='circle',size=1)
# 50个点的cos函数,用红色表示
data2 = 2.*numpy.pi*numpy.arange(100)/100.
data2.shape = (50,2)
data2[:,1] = numpy.cos(data2[:,0])
lines = wxPyPlot.PolyLine(data2, legend= 'Red Line', colour='red')
GraphTitle="Plot Data(Sin and Cos)"
return wxPyPlot.PlotGraphics([markers, lines],GraphTitle, "X Axis", "Y Axis")
#-----------------------------------------------------------------------------
class TestFrame1(wx.Frame):
def __init__(self, parent=None, id=wx.ID_ANY, title="Using wxPyPlot"):
wx.Frame.__init__(self, parent, id, title,size=(600, 400))
# 创建菜单栏
self.mainmenu = wx.MenuBar()
menu = wx.Menu()
menu.Append(100, 'Draw1', 'Draw plots1')
self.Bind(wx.EVT_MENU,self.OnPlotDraw1, id=100)
self.mainmenu.Append(menu, '&Plot')
self.SetMenuBar(self.mainmenu)
# 创建状态栏,显示信息
self.CreateStatusBar(2)
self.pc = wxPyPlot.PlotCanvas(self) #此处导入绘图面板
def OnPlotDraw1(self, event): #绘图函数
self.pc.Draw(MyDataObject())
###########################################################################
## 测试wxPyPlot的代码
###########################################################################
if __name__=='__main__':
app = wx.App()
tf=TestFrame1(None)
tf.Show()
app.MainLoop()
###########################################################################
###########################################################################
程序效果图为:
动态绘制折线
我们要实现动态图的绘制,就需要绘图动起来,所以我对程序做了去下修改,去掉了numpy模块,改用random来实现数据模拟代码如下
# -*- coding: utf-8 -*-
################################################################################
## 使用wxPython的绘图模块wxPyPlot,需要数据可视化的时候,无需再借用其他的库或模块了
################################################################################
import random
from time import sleep
import wx
import wx.lib.plot as wxPyPlot # 导入绘图模块,并命名为wxPyPlot
# ---------------------------------------------------------------------------
# 需要把数据封装进入MyDataObject中
def MyDataObject():
data1 = [[i,random.randint(0,9)] for i in range(100)]
lines1 = wxPyPlot.PolyLine(data1, legend='Green Markers', colour='blue')
data2 = [[i,random.randint(0,9)] for i in range(100)]
lines2 = wxPyPlot.PolyLine(data2, legend='Red Line', colour='red')
GraphTitle = "动态图的绘制"
return wxPyPlot.PlotGraphics([lines1, lines2], GraphTitle, "X", "Y")
# -----------------------------------------------------------------------------
class TestFrame1(wx.Frame):
def __init__(self, parent=None, id=wx.ID_ANY, title="Using wxPyPlot"):
wx.Frame.__init__(self, parent, id, title, size=(600, 400))
# 创建菜单栏
self.mainmenu = wx.MenuBar()
menu = wx.Menu()
menu.Append(100, 'Draw1', 'Draw plots1')
self.Bind(wx.EVT_MENU, self.OnPlotDraw1, id=100)
self.mainmenu.Append(menu, '&Plot')
self.SetMenuBar(self.mainmenu)
# 创建状态栏,显示信息
self.CreateStatusBar(2)
self.pc = wxPyPlot.PlotCanvas(self) # 此处导入绘图面板
def OnPlotDraw1(self, event): # 绘图函数
while True:
self.pc.Draw(MyDataObject())
sleep(2)
###########################################################################
## 测试wxPyPlot的代码
###########################################################################
if __name__ == '__main__':
app = wx.App()
tf = TestFrame1(None)
tf.Show()
app.MainLoop()
###########################################################################
###########################################################################
上面例子基本实现了数据的动态刷新,由于在事件函数动作的内部死循环,造成了wxpython界面的卡死,后面做功能组合的时候必须考虑多线程和定时器的使用。
窗口分割——水平分割窗口
本功能模块参考如影随形的绘制正弦曲线,如影随形源代码如下
下面代码引用 duzanuolu wxpython分割窗研究(解决sashPosition=0无效的BUG)
import wx
class Myframe(wx.Frame):
def __init__(self,flag=False):
wx.Frame.__init__(self,None)
self.sp=wx.SplitterWindow(self)# 创建一个分割窗
self.flag=flag
self.fisrt=0
self.p1=wx.Panel(self.sp,style=wx.SUNKEN_BORDER) #创建子面板
self.p2=wx.Panel(self.sp,style=wx.SUNKEN_BORDER)
self.p1.SetBackgroundColour("pink")
self.p2.SetBackgroundColour("blue")
self.p1.Hide() # 确保备用的子面板被隐藏
self.p2.Hide()
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBack)
self.sp.Unsplit()
self.sp.SplitHorizontally(self.p1, self.p2)
def OnEraseBack(self,event):
if self.fisrt<2 or self.flag :
self.sp.SetSashPosition(0)
self.fisrt=self.fisrt+1
event.Skip()
app = wx.App()
frame=Myframe(True)
frame.Show(True)
app.MainLoop()
可能他的代码用的wxpython版本太早了,现在运行有点问题,需要将wx.PySimpleApp()改为wx.App(),运行效果如下
分割窗口与绘画整合
整合分割窗口和绘图,使图形界面绘制在下面的分割窗口,代码如下:
import wx
import wx.lib.plot as wxPyPlot # 导入绘图模块,并命名为wxPyPlot
import random
def MyDataObject():
data1 = [[i,random.randint(0,9)] for i in range(100)]
lines1 = wxPyPlot.PolyLine(data1, legend='Green Markers', colour='blue')
data2 = [[i,random.randint(0,9)] for i in range(100)]
lines2 = wxPyPlot.PolyLine(data2, legend='Red Line', colour='red')
GraphTitle = "动态图的绘制"
return wxPyPlot.PlotGraphics([lines1, lines2], GraphTitle, "X", "Y")
class Myframe(wx.Frame):
def __init__(self,flag=False):
wx.Frame.__init__(self,None,size=(800,600))
self.mainmenu = wx.MenuBar()
menu = wx.Menu()
menu.Append(100, 'Draw1', 'Draw plots1')
self.mainmenu.Append(menu, '&Plot')
self.SetMenuBar(self.mainmenu)
self.sp=wx.SplitterWindow(self)# 创建一个分割窗
self.flag=flag
self.fisrt=0
self.p1=wx.Panel(self.sp,style=wx.SUNKEN_BORDER) #创建子面板
self.p2=wx.Panel(self.sp,style=wx.SUNKEN_BORDER)
self.p1.SetBackgroundColour("pink")
self.p2.SetBackgroundColour("#255255255255")
self.p1.Hide() # 确保备用的子面板被隐藏
self.p2.Hide()
self.plotter = wxPyPlot.PlotCanvas(self.p2, size=(800, 200))
self.plotter.SetInitialSize(size=self.p2.GetBestSize())
self.sp.Unsplit()
self.sp.SplitHorizontally(self.p1, self.p2)
self.Bind(wx.EVT_MENU, self.OnPlotDraw1)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBack)
def OnEraseBack(self,event):
if self.fisrt<2 or self.flag :
self.sp.SetSashPosition(0)
self.fisrt=self.fisrt+1
event.Skip()
def OnPlotDraw1(self, event): # 绘图函数
self.plotter.Draw(MyDataObject())
event.Skip()
app = wx.App()
frame=Myframe(True)
frame.Show(True)
app.MainLoop()
运行结果如下:
下一章博客将所有空间集中在一个窗口
特别感谢
本系列博客参考博客内容有以下帖子:
参考:wxFormBuilder摸索–小白上手–做一个编辑器,感谢caiza3491的技术分享
参考:wxpython分割窗研究(解决sashPosition=0无效的BUG),感谢duzanuolu的系列技术分享
参考:wxPython长时间任务处理,感谢CommandM的技术分享
参考:用wxpython 和numpy话画正弦曲线,感谢如影随形的技术分享
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)