问题
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.
回答1:
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:
- http://wiki.wxpython.org/Widget%20Inspection%20Tool
来源:https://stackoverflow.com/questions/24292756/python-wxpython-importing-csv-file-onto-wxgrid-not-displaying-to-fit-on-frame