views:

66

answers:

1

Hello, I want to create a dynamic image with python. There are three panels in the frame, title panel, image panel, and information panel. The image changes dynamically in the image panel. I use the OnTimer to update the image. There are two OnTimer, one in image panel, and the other in main frame. The OnTimer() in main frame will call the OnTimer() in image panel. But question arises, it the value in timer.Start() is small, sometimes the top panel and information panel disappear. The combobox is disabled. And also the image flashes a lot. Could anyone help to fix it? Thanks a lot.

import wx
import sys, time, os, gc
import wx.lib.colourselect as cs
import matplotlib.cm as cm

import numpy as npy
import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.figure import Figure

TIMER_ID = wx.NewId()

# Class TopPanel creates a Text display
class TopPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        font = wx.Font(20, wx.NORMAL, wx.NORMAL, wx.BOLD)
        self.st = wx.StaticText(self, -1, "Pseudo Image", (5,10), style=wx.ALIGN_CENTRE)
        self.st.SetFont(font)

        self.SetForegroundColour((164, 211, 238)) # lightskyblue2

# Class PlotPanel creates a Image display and intensity distribution
class PlotPanel(wx.Panel):    
    def __init__( self, parent, cmap=cm.jet, dpi=None, xpix=800, ypix=600, **kwargs):
        # initialize Panel
        if 'id' not in kwargs.keys():
            kwargs['id'] = wx.ID_ANY
        if 'style' not in kwargs.keys():
            kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE
        wx.Panel.__init__( self, parent, **kwargs )

        # initialize matplotlib stuff
        self.figure = Figure((10,8), 80)
        self.canvas = FigureCanvasWxAgg( self, -1, self.figure )

        rect = [0.065,0.065,0.85,0.85] 
        self.ax = self.figure.add_axes(rect)
        self.ax.xlim = ypix
        self.ax.ylim = xpix
        self.ax.set_xlim([0, self.ax.xlim])
        self.ax.set_ylim([self.ax.ylim, 0])
        self.cmap = cmap

        self.Bind(wx.EVT_TIMER, self.OnTimer)

    def InitPlot(self):
        self.x = npy.empty((self.ax.xlim,self.ax.ylim))
        self.x.flat = npy.arange(self.ax.ylim)*2*npy.pi/float(self.ax.ylim)
        self.y = npy.empty((self.ax.ylim,self.ax.xlim))
        self.y.flat = npy.arange(self.ax.xlim)*2*npy.pi*5.0/(self.ax.xlim*4.0)
        self.y = npy.transpose(self.y)
        z = npy.fabs(npy.sin(self.x)/2. + npy.cos(self.y)/2.)
        self.im = self.ax.imshow( z, cmap=self.cmap)#, interpolation='nearest')

        self.im.set_array(z)
        self.canvas.draw()

    def OnTimer(self, evt):
        self.x += npy.pi/15
        self.y += npy.pi/20
        z = npy.fabs(npy.sin(self.x) + npy.cos(self.y))
        self.im.set_array(z)
  #      self.onEraseBackground(evt)
        self.canvas.draw()

class InfoPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        font = wx.Font(20, wx.NORMAL, wx.NORMAL, wx.BOLD)
        vbox = wx.BoxSizer(wx.VERTICAL)

        xlabel = wx.StaticText(self, -1, 'X Pixels:', (20, -1))
        xtext = wx.TextCtrl(self, -1, "800", style=wx.TE_READONLY|wx.NO_BORDER, size=(50,-1))
        xtext.SetBackgroundColour("gray")

        ylabel = wx.StaticText(self, -1, 'Y Pixels:', (20, -1))
        ytext = wx.TextCtrl(self, -1, "600", size=(50,-1), style=wx.TE_READONLY|wx.NO_BORDER)
        ytext.SetBackgroundColour("gray")

        tsizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)
        tsizer.AddMany([xlabel, xtext, ylabel, ytext])

        vbox.Add(tsizer, 9, wx.ALL)
        self.SetSizer(vbox)

        cmaplabel = wx.StaticText(self, -1, 'C Map', (20, -1))
        cmapList = ['jet', 'hot', 'cool', 'spectral']
        cb = wx.ComboBox(self, -1, "jet", (90, 80), (120, -1), cmapList, style=wx.CB_DROPDOWN)

        tsizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)
        tsizer.AddMany([xlabel, xtext, ylabel, ytext, cmaplabel, cb])

        vbox.Add(tsizer, 9, wx.ALL)
        self.SetSizer(vbox)
        self.Bind(wx.EVT_COMBOBOX, self.OnSelect, cb)

    def OnSelect(self, evt):
        cmap = evt.GetSelection()
        self.SetCmap(cmap)

    def SetCmap(self, value):
        cmap = value
        return cmap


class MyFrame(wx.Frame):

    def __init__(self):


        wx.Frame.__init__(self, None, title="Test", size=(1200,1000))

        self.top_panel = TopPanel(self)
        self.plt_panel = PlotPanel(self)
        self.side_panel = InfoPanel(self)

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(self.top_panel, 0, wx.ALIGN_CENTRE|wx.TOP, 10)

        downSizer= wx.BoxSizer(wx.HORIZONTAL)        
        downSizer.Add(self.plt_panel, 0, wx.EXPAND, 20)
        downSizer.Add(self.side_panel, 1, wx.RIGHT, 20)

        mainSizer.Add(downSizer, 0, wx.BOTTOM)
        self.SetSizer(mainSizer)

        self.timer = wx.Timer(self, TIMER_ID)
        self.Bind(wx.EVT_TIMER, self.OnTimer,self.timer)

        mainSizer.Fit(self)
        self.plt_panel.InitPlot()


        self.timer = wx.Timer(self, TIMER_ID)
        self.Bind(wx.EVT_TIMER, self.OnTimer,self.timer)
        self.timer.Start(10)

    def OnTimer(self, evt):
        self.plt_panel.OnTimer(evt)


app = wx.App(False)
frame = MyFrame()
frame.Show()
app.MainLoop()
+1  A: 

Thanks for your help. The program seem works well when the computation is simple.

hopefullin