繁体   English   中英

在Wx应用程序中嵌入visvis图形

[英]Embedding visvis figure in a wx application

下面的代码尝试将visvis图形嵌入wx应用程序以制作具有3D数据的电影。 问题是,每次我朗读代码时,都会收到错误消息

“ ./src/unix/glx11.cpp(86):在SetCurrent()中断言“ xid”失败:必须显示窗口”,在调用Figure = app.GetFigureClass()self.fig = Figure(self)之后

我花了一些时间研究这个错误,但是没有一个答案适合我。 有谁知道如何解决?

import wx
import h5py
import numpy as np
import visvis as vv

app = vv.use('wx')

class CPlot3D (wx.Frame) :
    """
    Class for plotting 3D Dirac 
    """

    def data_for_plotting (self, frame_number) :
        """
        Load the data to be plotted for the frame with the frame_number 
        """
        frame = str(self.frame_names[frame_number])
        return self.f[frame][...]

    def draw_curent_frame (self, event=None) :
        """
        Display the current frame
        """
        # Load data
        data = self.data_for_plotting (self.frame_number.GetValue())    

        try :
            self.volume_plot.SetData (data)
        except AttributeError :
            vv.clf()
            self.volume_plot = vv.volshow (data, clim=(self.global_min, self.global_max), renderStyle='mip', cm=vv.CM_JET)
            a = vv.gca()
            vv.ColormapEditor(a)

            def GetTicks (axis_num, min_val, max_val, label_format="%.2f") :
                size = data.shape[axis_num]
                # Number of ticks
                nticks = int(np.ceil(np.log2(size)))
                nticks += 1 - nticks % 2 # Make <nticks> odd
                ticks_position = np.linspace(0, size-1, nticks)
                ticks_label = map( lambda x : label_format % x, np.linspace(min_val, max_val, nticks) ) 
                return dict( zip(ticks_position, ticks_label)  )

            a.axis.xTicks = GetTicks(0, self.x_min, self.x_max) 
            a.axis.xLabel = "x (rel. units)"

            a.axis.yTicks = GetTicks(1, self.y_min, self.y_max) 
            a.axis.yLabel = "y (rel. units)"

            a.axis.zTicks = GetTicks(2, self.z_min, self.z_max) 
            a.axis.zLabel = "z (rel. units)"

            self.fig.Draw()


    def __init__ (self, parent, file_name, title="Plot Dirac 3D") :
        # Open files
        self.f = h5py.File (file_name, 'r')

        # Extract the dimension
        self.x_gridDIM = int(self.f['x_gridDIM'][...])
        self.y_gridDIM = int(self.f['y_gridDIM'][...])
        self.z_gridDIM = int(self.f['z_gridDIM'][...])

        self.dx = self.f['dx'][...]

        self.x_min = self.f['x_min'][...]
        self.x_max = self.x_min + self.x_gridDIM * self.dx

        self.y_min = self.f['y_min'][...]
        self.y_max = self.y_min + self.y_gridDIM * self.dx

        self.z_min = self.f['z_min'][...]
        self.z_max = self.z_min + self.z_gridDIM * self.dx


        # Collect the frame names
        self.frame_names = []

        for key in self.f.keys () :
            try : self.frame_names.append (int(key)) 
            except ValueError: pass

        self.frame_names.sort ()

        print "\nGet global maximum and minimum..."

        # Find the min and max values in all the frames
        for frame_number in range(len(self.frame_names)) :
            data = self.data_for_plotting (frame_number)
            try :           
                self.global_min = min( self.global_min, data.min() )
                self.global_max = max( self.global_max, data.max() )
            except AttributeError :
                self.global_min = data.min()
                self.global_max = data.max()  

        print "\nStart animation..."

        # Create GUI
        dw, dh = wx.DisplaySize()
        wx.Frame.__init__ (self, parent, title=title, size=(0.4*dw, 0.6*dh) )

        self.ConstructGUI ()
        self.Center()
        self.Show ()
        wx.EVT_CLOSE(self, self.on_close)
        self.On_animation_button ()

    def on_close (self, event) :
        try : self.animation_timer.Stop() 
        except AttributeError : pass
        self.Destroy()

    def ConstructGUI (self) :
        """
        Make a GUI
        """
        ######################### Navigation bar ##############################
        panel = wx.Panel(self)  
        boxsizer = wx.BoxSizer (wx.HORIZONTAL)

        # Frame number indicator    
        boxsizer.Add (wx.StaticText(panel, label="Frame Number:"))
        self.frame_number = wx.SpinCtrl (panel, value="0", min=0, max=len(self.frame_names)-1)
        self.frame_number.Bind (wx.EVT_SPINCTRL, self.draw_curent_frame )
        boxsizer.Add (self.frame_number)

        # Go to the beginning button
        self.go_beginnign_button = wx.Button (panel, label="<<")
        self.Bind (wx.EVT_BUTTON, self.go_to_beginning, self.go_beginnign_button)
        boxsizer.Add (self.go_beginnign_button) 

        # Animation button
        self.animation_button_start_label = "Play  animation  "
        self.animation_button_stop_label =  "STOP animation"
        self.animation_button = wx.Button (panel, label=self.animation_button_start_label) 
        self.Bind (wx.EVT_BUTTON, self.On_animation_button, self.animation_button)
        boxsizer.Add (self.animation_button)

        # Go to the end button
        self.go_end_button = wx.Button (panel, label=">>")
        self.Bind (wx.EVT_BUTTON, self.go_to_end, self.go_end_button)
        boxsizer.Add (self.go_end_button) 

        panel.SetSizer (boxsizer)   
        ############################# Setting up visvis binding #######################################
        Figure = app.GetFigureClass()
        self.fig = Figure(self)
        ################################### Layout #####################################################    
        sizer = wx.BoxSizer (wx.VERTICAL)
        sizer.Add (panel, flag=wx.CENTER)
        sizer.Add(self.fig._widget, 1, flag=wx.EXPAND)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.Layout() 


    def On_animation_button (self, event=None) :
        """
        <self.animation_button> was clicked
        """
        if self.animation_button.GetLabel() == self.animation_button_start_label :
            # Begin playing animation

            # Set up timer for animation
            timer_id = wx.NewId ()
            self.animation_timer = wx.Timer (self, timer_id) 
            self.animation_timer.Start (200)

            def on_animation_timer (event) :
                self.draw_curent_frame() 
                position = self.frame_number.GetValue()
                if position > len(self.frame_names)-2 : self.On_animation_button ()         
                else : self.frame_number.SetValue (position+1)

            wx.EVT_TIMER (self, timer_id, on_animation_timer)  
            # Channing the button's label
            self.animation_button.SetLabel(self.animation_button_stop_label)
        else : # Stop playing animation
            self.animation_timer.Stop ()
            del self.animation_timer
            # Channing the button's label
            self.animation_button.SetLabel(self.animation_button_start_label)

    def go_to_beginning (self, event) :
        """
        <self.go_beginnign_button> was clicked
        """
        self.frame_number.SetValue (0)  
        self.draw_curent_frame()

    def go_to_end (self, event) :
        """
        <self.go_end_button> was clicked
        """
        self.frame_number.SetValue (len(self.frame_names)-1)
        self.draw_curent_frame()

if __name__ == '__main__' :

    import sys
    app.Create()

    # Loading files
    if len(sys.argv) <> 2 :
        openFileDialog = wx.FileDialog(None, "Open HDF5 file to load 3D Dirac", "", "",
                                       "HDF5 files (*.hdf5)|*.hdf5", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_CHANGE_DIR)
        # Check whether user canceled
        if openFileDialog.ShowModal() == wx.ID_CANCEL:
            print "Error:  file name is  needed as argument"
            exit()
        else : filename = openFileDialog.GetPath()  

    else : filename = sys.argv[1]

    CPlot3D (None, filename)
    app.Run ()

当您手动调用On_animation_button() ,即使您已在其上调用Show() ,实际上仍未显示该框架,因为至少在X11中,显示是异步发生的。 因此,您需要将其延迟到以后再调用。 这可以通过将执行此操作的lambda绑定到EVT_SIZE事件来EVT_SIZE (因为在您获取该事件时,该窗口已经初始化),或者仅使用CallAfter()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM