Python光学仿真wxpython透镜演示系统初始化与参数调节

拾光
拾光
发布时间:2026-10-15 | 3人浏览过
原创

本文详解Python光学仿真系统中基于wxpython的透镜演示界面初始化与参数调节实现。重点解析如何利用wx.NoteBook实现选项卡切换,并通过lambda表达式结合字典结构,高效创建并绑定多个滚动条事件,实现光学参数的动态调整与实时绘图。

初始化与参数调节面板

本节将展示如何绘制出如下图所示的参数调节面板。

针对上述界面,BoxSizer布局虽然直观,但有两个关键点需要关注:一是opti和source这两个选项卡的具体实现方式,二是如何同时创建多个滚动条控件。

实现第一个关键点相对简单,主要涉及使用wx.NoteBook控件。其用法较为常规,具体实现细节可参考后续代码示例。

实现多个滚动条同样可以直接罗列控件,但若涉及五个不同参数,则需新建五组滚动条及对应的五个控制函数。由于这五个函数的功能高度相似,直接罗列会导致代码冗余,因此我们采用以下优化方案进行精简。


def InitPanel(self):
    self.drawPanel = wx.Panel(self) #绘图面板
    #########初始化paraBook
    paraBook = wx.Notebook(self,size=(300,-1))
    optiPanel = wx.Panel(paraBook)
    sourcePanel = wx.Panel(paraBook)
    paraBook.AddPage(optiPanel,'opti')
    paraBook.AddPage(sourcePanel,'source')
    ###需要初始化edge
    self.setEdge()
    ####################optiBox###################
    self.paraSliders = {}
    optiBox = wx.BoxSizer(wx.VERTICAL)
    for key in self.optiDict:
        self.paraSliders[key]=wx.Slider(
            optiPanel,minValue=1,maxValue=1000,size=(200,-1))
        self.paraSliders[key].Bind(wx.EVT_SCROLL,
            lambda evt,mark=key: self.OnSliderScroll(evt,mark))
        optiBox.Add(self.paraSliders[key],proportion=1,
            flag=wx.LEFT|wx.CENTER)
        optiBox.Add(wx.StaticText(optiPanel,size=(120,30),label=key,
            style=wx.ALIGN_RIGHT),proportion=1,
            flag=wx.ALIGN_CENTER, border=10)
    self.testFlag = wx.TextCtrl(
        optiPanel,size=(250,400),value='hellos',style=wx.TE_MULTILINE)
    optiBox.Add(self.testFlag,proportion=1,
        flag=wx.ALIGN_CENTER|wx.ALL|wx.ALIGN_RIGHT,border=0)
    optiPanel.SetSizer(optiBox)
    ####################sourceBox###################
    sourceBox = wx.BoxSizer(wx.VERTICAL)
    for key in self.sourceDict:
        self.paraSliders[key]=wx.Slider(
            sourcePanel,minValue=1,maxValue=1000,size=(200,-1))
        self.paraSliders[key].Bind(wx.EVT_SCROLL,
            lambda evt,mark=key: self.OnSliderScroll(evt,mark))
        sourceBox.Add(self.paraSliders[key],proportion=1,
            flag=wx.LEFT|wx.CENTER)
        sourceBox.Add(wx.StaticText(sourcePanel,size=(120,30),label=key,
            style=wx.ALIGN_RIGHT),proportion=1,
            flag=wx.ALIGN_CENTER, border=10)
    sourcePanel.SetSizer(sourceBox)
    mainBox = wx.BoxSizer()
    mainBox.Add(self.drawPanel,proportion=1,flag=wx.ALL|wx.EXPAND,border=10)
    mainBox.Add(paraBook,proportion=0,flag=wx.ALL|wx.EXPAND,border=10)
    self.SetSizer(mainBox)
def OnSliderScroll(self,evt,mark):
    paraArea = {'ySource':[-300,300],'xSource':[0,1000],
                'xPos':[0,1200],'Diameter':[0,500],
                'lFocal':[-1000,1000],'rFocal':[-1000,1000],
                'theta':[0,np.pi*2],'nOpti':[0.1,10]}
    pValue = self.paraSliders[mark].GetValue()
    pMin,pMax=paraArea[mark]
    if mark in self.optiDict:
        self.optiDict[mark] = pMin+(pMax-pMin)/1000*pValue
    elif mark in self.sourceDict:
        self.sourceDict[mark]=pMin+(pMax-pMin)/1000*pValue
    pStr = ''
    for key in self.optiDict:
        pStr += key+':'+str(self.optiDict[key])+'\n'
    self.setEdge()  #设置光学元件
    self.getRay()   #计算
    self.DrawPath() #绘图

上述代码的关键在于使用了lambda表达式,使得事件函数能够接收两个参数,从而一次性完成多个控件的创建与绑定。

具体实现步骤如下:首先创建一个滚动条字典。


 self.paraSliders = {}

该字典的键为变量名称,值对应具体的滚动条控件。其实现代码如下。


self.paraSliders[key]=wx.Slider(optiPanel,minValue=1,maxValue=1000,size=(200,-1))

随后,为每个滚动条通过lambda绑定事件函数。


self.paraSliders[key].Bind(wx.EVT_SCROLL,lambda evt,mark=key: self.OnSliderScroll(evt,mark))

其中,wx.EVT_SCROLL代表滚动事件。通过lambda方法将事件对象evt和标记值mark传入事件函数self.OnSliderScroll(evt,mark),此时mark的值即为当前字典的键值。

最后,将创建好的滚动条添加到Boxsizer布局中。

在调用的OnSliderScroll方法中,首先定义参数字典以确定不同滚动条的滚动范围。通过mark值,实现参数与滚动条的一一对应。接着,设置成员变量self.optiDict以及self.sourceDict以更新系统状态。

以上即为Python光学仿真wxpython透镜演示系统初始化与参数调节的详细内容。如需了解更多关于wxpython透镜演示系统初始化与参数调节的资料,请持续关注本站其他相关文章。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表