1

Am working on a project where I have to import CSV files into wx.Grid for further manipulations. I have searched and found a useful way here http://wxpython-users.1045709.n5.nabble.com/new-to-the-list-opening-a-text-file-in-a-grid-using-splitterwindows-td2373808.html

Now my CSV never seems to display on my screen frame at all (as per the code below)? Any way around this?

csv1.py is the GUI

class MyFrame3 ( wx.Frame ):

    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 900,600 ), style = wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX|wx.SYSTEM_MENU|wx.TAB_TRAVERSAL )

        self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )

        Sizer1 = wx.BoxSizer( wx.HORIZONTAL )

        Sizer1.SetMinSize( wx.Size( 0,0 ) ) 
        self.Right_Panel = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        RightSizer = wx.BoxSizer( wx.VERTICAL )


        self.Right_Panel.SetSizer( RightSizer )
        self.Right_Panel.Layout()
        RightSizer.Fit( self.Right_Panel )
        Sizer1.Add( self.Right_Panel, 1, wx.EXPAND |wx.ALL, 5 )

        self.Left_Panel = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        LeftSizer = wx.BoxSizer( wx.VERTICAL )

        self.ImportButton = wx.Button( self.Left_Panel, wx.ID_ANY, u"Import CSV File", wx.DefaultPosition, wx.DefaultSize, 0 )
        LeftSizer.Add( self.ImportButton, 0, wx.ALL, 5 )


        self.Left_Panel.SetSizer( LeftSizer )
        self.Left_Panel.Layout()
        LeftSizer.Fit( self.Left_Panel )
        Sizer1.Add( self.Left_Panel, 0, wx.EXPAND |wx.ALL, 5 )


        self.SetSizer( Sizer1 )
        self.Layout()
        self.menubar = wx.MenuBar( 0 )
        self.fileMenu = wx.Menu()
        self.importMenu = wx.MenuItem( self.fileMenu, wx.ID_ANY, u"Import", wx.EmptyString, wx.ITEM_NORMAL )
        self.fileMenu.AppendItem( self.importMenu )

        self.menubar.Append( self.fileMenu, u"&File" ) 

        self.SetMenuBar( self.menubar )


        self.Centre( wx.BOTH )

        # Connect Events
        self.ImportButton.Bind( wx.EVT_BUTTON, self.ImportFunc )
        self.Bind( wx.EVT_MENU, self.ImportFunc, id = self.importMenu.GetId() )



class csv_view(wx.App): 
        def OnInit(self): 
                self.frame=MyFrame3(None, -1, 'PyStereo', size=(900,600)) 
                self.SetTopWindow(self.frame) 
                return True 

csv2.py is the running script

#!/usr/bin/python
# -*- coding: utf-8 -*- 

import wx
import os
import numpy as np
import sys, csv
import wx.grid
from csv1 import MyFrame3, csv_view




class MyFrame(MyFrame3):
    def __init__(self, parent, size = wx.Size(900,600)):
        MyFrame3.__init__ (self, parent)

        self.dirname = os.getcwd()



    # Import/Open CSV

    def ImportFunc( self, event ):
        '''THIS IMPORTED CSV WILL NEVER EXPAND TO FIT INTO THE FRAME, PLEASE HELP?'''   

        dlg=wx.FileDialog(self, 'Choose a file', self.dirname, '','CSV files (*.csv)|*.csv|All files(*.*)|*.*',wx.OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            self.dirname=dlg.GetDirectory()
            self.filename=os.path.join(self.dirname,dlg.GetFilename())
            self.file=file(self.filename, 'r')

            #check for file format with sniffer
            dialect = csv.Sniffer().sniff(self.file.read(1024))
            self.file.seek(0)

            csvfile=csv.reader(self.file,dialect)
            filedata = [] #put contents of csvfile into a list
            filedata.extend(csvfile)
            self.file.seek(0)

            #grab a sample and see if there is a header
            sample=self.file.read(2048)
            self.file.seek(0)
            if csv.Sniffer().has_header(sample): #if there is a header
                colnames=csvfile.next() # label columns from first line
                datalist=[] # create a list without the header
                datalist.extend(filedata[1:len(filedata)]) #append data without header

            else:
                row1=csvfile.next() #if there is NO header
                colnames=[]
                for i in range(len(row1)):
                    colnames.append('col_%d' % i) # label columns as col_1, col_2, etc
                self.file.seek(0)
                datalist=filedata #append data to datalist

        self.file.close()
        self.createGrid(datalist, colnames)



    #create the grid

    def createGrid(self, datalist, colnames):
        if getattr(self, 'grid', 0): self.grid.Destroy()
        self.grid=wx.grid.Grid(self, 0)
        self.grid.CreateGrid(len(datalist), len(colnames)) #create grid, same size as file (rows, cols)

        #fill in headings
        for i in range(len(colnames)):
            self.grid.SetColLabelValue(i, colnames[i])

        #populate the grid
        for row in range(len(datalist)):
            for col in range(len(colnames)):
                try: 
                    self.grid.SetCellValue(row,col,datalist[row][col])
                except: 
                    pass


        self.grid.AutoSizeColumns(False) # size columns to data (from cvsomatic.py)
        self.twiddle()

    def twiddle(self): # from http://www.velocityreviews.com/forums/t330788-how-to-update-window-after-wxgrid-is-updated.html
        x,y = self.GetSize()
        self.SetSize((x, y+1))
        self.SetSize((x,y))

    def Exit(self, event):
        if getattr(self, 'file',0):
            self.file.close()
            self.Close(True)

# class csv_view(wx.App):
#   def OnInit(self):
#       self.frame=MyFrame(None, -1, 'show CSV', size=(900,600))
#       self.SetTopWindow(self.frame)
#       return True


# app=csv_view() 
# app.MainLoop() 



app = wx.App(0)
Frame_02 = MyFrame(None)
Frame_02.Show()
app.MainLoop()

Thanks for your help in advance.

Umar Yusuf
  • 926
  • 2
  • 13
  • 30

1 Answers1

2

The biggest issue is that you have a parenting problem. When you create the grid widget, you add it to the frame, but not to a sizer. That causes the grid to be initialized to a small size and it gets stacked on top of the panel. To fix this, you need to set the parent of the grid to one of the panels, add the grid to a sizer and then call Layout on the panel. Here's the updated code for csv2.py:

import wx
import os
import sys, csv
import wx.grid
from csv1 import MyFrame3

class MyFrame(MyFrame3):
    def __init__(self, parent, size = wx.Size(900,600)):
        MyFrame3.__init__ (self, parent)

        self.dirname = os.getcwd()



    # Import/Open CSV

    def ImportFunc( self, event ):
        '''THIS IMPORTED CSV WILL NEVER EXPAND TO FIT INTO THE FRAME, PLEASE HELP?'''   

        dlg=wx.FileDialog(self, 'Choose a file', self.dirname, '','CSV files (*.csv)|*.csv|All files(*.*)|*.*',wx.OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            self.dirname=dlg.GetDirectory()
            self.filename=os.path.join(self.dirname,dlg.GetFilename())
            self.file=file(self.filename, 'r')

            #check for file format with sniffer
            dialect = csv.Sniffer().sniff(self.file.read(1024))
            self.file.seek(0)

            csvfile=csv.reader(self.file,dialect)
            filedata = [] #put contents of csvfile into a list
            filedata.extend(csvfile)
            self.file.seek(0)

            #grab a sample and see if there is a header
            sample=self.file.read(2048)
            self.file.seek(0)
            if csv.Sniffer().has_header(sample): #if there is a header
                colnames=csvfile.next() # label columns from first line
                datalist=[] # create a list without the header
                datalist.extend(filedata[1:len(filedata)]) #append data without header

            else:
                row1=csvfile.next() #if there is NO header
                colnames=[]
                for i in range(len(row1)):
                    colnames.append('col_%d' % i) # label columns as col_1, col_2, etc
                self.file.seek(0)
                datalist=filedata #append data to datalist

        self.file.close()
        self.createGrid(datalist, colnames)
        grid_sizer = wx.BoxSizer(wx.VERTICAL)
        grid_sizer.Add(self.grid, 1, wx.EXPAND)
        self.Right_Panel.SetSizer(grid_sizer)
        self.Right_Panel.Layout()



    #create the grid

    def createGrid(self, datalist, colnames):
        if getattr(self, 'grid', 0): self.grid.Destroy()
        self.grid=wx.grid.Grid(self.Right_Panel, 0)
        self.grid.CreateGrid(len(datalist), len(colnames)) #create grid, same size as file (rows, cols)

        #fill in headings
        for i in range(len(colnames)):
            self.grid.SetColLabelValue(i, colnames[i])

        #populate the grid
        for row in range(len(datalist)):
            for col in range(len(colnames)):
                try: 
                    self.grid.SetCellValue(row,col,datalist[row][col])
                except: 
                    pass


        self.grid.AutoSizeColumns(False) # size columns to data (from cvsomatic.py)
        self.twiddle()

    def twiddle(self): # from http://www.velocityreviews.com/forums/t330788-how-to-update-window-after-wxgrid-is-updated.html
        x,y = self.GetSize()
        self.SetSize((x, y+1))
        self.SetSize((x,y))

    def Exit(self, event):
        if getattr(self, 'file',0):
            self.file.close()
            self.Close(True)

import wx.lib.mixins.inspection
app = wx.App(0)
Frame_02 = MyFrame(None)
Frame_02.Show()
wx.lib.inspection.InspectionTool().Show()
app.MainLoop()

I also added the Widget Inspection Tool to your code to help me figure out how the panels were laid out and where to put the grid. It is very useful for figuring out problems with widget layout. You can read more about this handy tool on the wxPython wiki:

Mike Driscoll
  • 32,629
  • 8
  • 45
  • 88
  • 1
    Perfectly done. Thanks a million times Mike! By the way, am still having difficulties with my question here=> http://stackoverflow.com/questions/24240580/wxpython-reportlab-how-to-create-and-open-a-pdf-file-on-button-clicked I can figure out how to load the “class Launcher”? – Umar Yusuf Jun 19 '14 at 17:18