如何在while循环运行Python时修改变量

时间:2017-01-05 10:21:51

标签: python-2.7 function while-loop wxpython vpython

我正在使用wx.python和VPython来制作轨道模拟器,但是我在尝试使用GUI中的滑块来实现模拟时遇到了麻烦,我认为这是因为我正在尝试获取与滑块按钮关联的数字,以便在运行时进入while循环。

所以我的问题是,如何在位于代码底部的while循环中更新函数SetRate? (我已经检查过滑块是否重新调整值)

以下是我的参考代码:

Value = 1.0
dt = 100.0

def InputValue(Value):
    dt = Value

def SetRate(evt):
    global Value
    Value = SpeedOfSimulation.GetValue()
    return Value


    w = window(menus=True, title="Planetary Orbits",x=0, y=0, width = 1000, height = 1000)
    Screen = display(window = w, x = 30, y = 30, width = 700, height = 500)
    gdisplay(window = w, x = 80, y = 80 , width = 40, height = 20)

    p = w.panel # Refers to the full region of the window in which to place widgets

    SpeedOfSimulation = wx.Slider(p, pos=(800,10), size=(200,100), minValue=0, maxValue=1000)
    SpeedOfSimulation.Bind(wx.EVT_SCROLL, SetRate)


    TestData = [2, 0, 0, 0, 6371e3, 5.98e24, 0, 0, 0, 384400e3, 0, 0, 1737e3, 7.35e22, 0, 1e3, 0]
    Nstars = TestData[0]  # change this to have more or fewer stars

    G = 6.7e-11 # Universal gravitational constant

    # Typical values
    Msun = 2E30
    Rsun = 2E9
    vsun = 0.8*sqrt(G*Msun/Rsun)

    Stars = []
    colors = [color.red, color.green, color.blue,
              color.yellow, color.cyan, color.magenta]
    PositionList = []
    MomentumList = []
    MassList = []
    RadiusList = []

    for i in range(0,Nstars):
        s=i*8
        x = TestData[s+1]
        y = TestData[s+2]
        z = TestData[s+3]
        Radius = TestData[s+4]
        Stars = Stars+[sphere(pos=(x,y,z), radius=Radius, color=colors[i % 6],
                       make_trail=True, interval=10)]
        Mass = TestData[s+5]
        SpeedX = TestData[s+6]
        SpeedY = TestData[s+7]
        SpeedZ = TestData[s+8]
        px = Mass*(SpeedX)
        py = Mass*(SpeedY)
        pz = Mass*(SpeedZ)
        PositionList.append((x,y,z))
        MomentumList.append((px,py,pz))
        MassList.append(Mass)
        RadiusList.append(Radius)

    pos = array(PositionList)
    Momentum = array(MomentumList)
    Mass = array(MassList)
    Mass.shape = (Nstars,1) # Numeric Python: (1 by Nstars) vs. (Nstars by 1)
    Radii = array(RadiusList)

    vcm = sum(Momentum)/sum(Mass) # velocity of center of mass
    Momentum = Momentum-Mass*vcm # make total initial momentum equal zero


    Nsteps = 0
    time = clock()
    Nhits = 0

    while True:
        InputValue(Value)  #Reprensents the change in time 
        rate(100000)   #No more than 100 loops per second on fast computers

        # Compute all forces on all stars
        r = pos-pos[:,newaxis] # all pairs of star-to-star vectors (Where r is the Relative Position Vector
        for n in range(Nstars):
            r[n,n] = 1e6  # otherwise the self-forces are infinite
        rmag = sqrt(sum(square(r),-1)) # star-to-star scalar distances
        hit = less_equal(rmag,Radii+Radii[:,newaxis])-identity(Nstars)
        hitlist = sort(nonzero(hit.flat)[0]).tolist() # 1,2 encoded as 1*Nstars+2
        F = G*Mass*Mass[:,newaxis]*r/rmag[:,:,newaxis]**3 # all force pairs

        for n in range(Nstars):
            F[n,n] = 0  # no self-forces
        Momentum = Momentum+sum(F,1)*dt

        # Having updated all momenta, now update all positions         
        pos = pos+(Momentum/Mass)*dt

        # Update positions of display objects; add trail
        for i in range(Nstars):
            Stars[i].pos = pos[i]

1 个答案:

答案 0 :(得分:0)

我对vpython一无所知,但在普通的wxPython应用程序中,你将使用wx.Timer而不是while循环。

这是从https://www.blog.pythonlibrary.org/2009/08/25/wxpython-using-wx-timers/

修改的wx.Timer的示例

您需要将while循环部分与SetRate类方法分开,并将其放在update中。

import wx

class MyForm(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Timer Tutorial 1", 
                                   size=(500,500))

        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)

        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.update, self.timer)

        SpeedOfSimulation = wx.Slider(p, pos=(800,10), size=(200,100), minValue=0, maxValue=1000)
        SpeedOfSimulation.Bind(wx.EVT_SCROLL, SetRate)
        self.SpeedOfSimulation = SpeedOfSimulation

    def update(self, event):

      # Compute all forces on all stars

      SpeedOfSimulation = self.SpeedOfSimulation.GetValue()