Hi -
This may be more an issue of me not understanding oop, so
perhaps this
will be an easy question for someone to pick off.
I am trying to write a small program to manage information
involved in
crystallizing proteins. Our standard experimental format is
an 8x12
plastic tray. The experiment involves refining the
conditions (pH,
various chemical concentrations, etc). This involves both
record
keeping and calculations to determine proper mixing ratios.
So - I
thought a GUI based on the wxPython Grid class would be
perfect.
The composition of each well can be considered in layers, so
I've set
up a GUI that uses the grid widget and have included it with
buttons
so that the 'layers' can be selected. I also have
pulldown menus -
ultimately I would like to be able to generate printouts of
mixing
ratios, etc from the values that have been entered into the
grid.
The problem is that I am stuck at trying to make a link
between the
button widgets and the grid widget. The buttons work, the
grid works,
but I cannot get the buttons to talk to the grid.
I am including my code. Much of it is just off the shelf
wxPython
picked up from tutorials and the 'wxPython in Action'. I
had a
version of this working whereby I reserved a column of cells
in the
grid that could detect actions, but I would prefer to use
actual
buttons for a button-type action!
Any help is appreciated. Code follows below. This is meant
to run on
Windows XP with Python 2.4 and wxPython 2.6. I intend to
port it over
to Linux when I get it working under Windows.
Thanks!
--------code start--------------
import wx
import wx.grid
import os
import sys
####
ID_ABOUT=101
ID_OPEN=102
ID_SAVE=103
ID_BUTTON1=110
ID_EXIT=200
############
#-----------------------------------
#Working array for data
###########################################################3
#
# Salt
#
salt_conc_row1 = ['0.0']*4 + ['0.1']*4 + ['0.2']*4
salt_conc = salt_conc_row1 * 8
#salt_conc_row1 = ['0.2']*6 + ['0.0']*6
#salt_conc = ['0.1']*48 + ['0.2']*48
salt_comp = ['NaCl']*96
#salt_cmpd = ['NaCl']*96
###################################################333
#
# Buffer (has extra pH statement)
#
ph_row1 = ['5.1']*12
ph_row2 = ['5.2']*12
ph_row3 = ['5.3']*12
ph_row4 = ['5.4']*12
ph_row5 = ['5.5']*12
ph_row6 = ['5.6']*12
ph_row7 = ['5.7']*12
ph_row8 = ['5.8']*12
ph = ph_row1 + ph_row2 + ph_row3 + ph_row4 + ph_row5 +
ph_row6 +
ph_row7 + ph_row8
#ph_row1 =
['5.0','5.4','5.8','6.2','6,6','7.0','7.4','7
.8','8.2','8.6','9.0','0']
#ph = ph_row1 * 8
buff_conc = (['0.1'])*96
buff_comp1 = ['citrate']*36
buff_comp2 = ['tris']*48
buff_comp3 = ['none']*12
buff_comp = buff_comp1 + buff_comp2 + buff_comp3
#buff_comp_row1 = ['citrate']*5 + ['tris']*6 +
['none']
#buff_comp = ['citrate'] * 96
###################################################
#
# Then the precipitants. Define a,b,c for multiple
precipitants
#
ppt_conc_row1 = ['4','8','12','16']*3
ppt_conc = ppt_conc_row1 * 8
ppt_comp = ["PEG8K"]*96
ppt_unit = ["% "]*96
# This sets up a dictionary to translate from
# the linear list of values to a 12x8 plate grid(96 well
plate)
line_to_96plate={}
n=0
grid_columns = 12
grid_rows = 8
for x in range(grid_rows):
for y in range(grid_columns):
line_to_96plate[n]=[x,y]
n=n+1
button_push = 0
current_view=[]
for x in range(96):
current_view.append(buff_comp[x] + " " +
(ph[x]))
##################
class TestTable(wx.grid.PyGridTableBase):
def __init__(self):
wx.grid.PyGridTableBase.__init__(self)
self.data={}
for x in range(96):
self.data[((line_to_96plate[x][0]),(line_to_96plate[x][1]))]
=current_view[x]
# these five are the required methods
def GetNumberRows(self):
return 8
def GetNumberCols(self):
return 12
def IsEmptyCell(self, row, col):
return self.data.get((row, col)) is not None
def GetValue(self, row, col):
value = self.data.get((row, col))
if value is not None:
return value
else:
return ''
def SetValue(self, row, col, value):
self.data[(row,col)] = value
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Grid
Table",
size=(1120,620))
grid = wx.grid.Grid(self)
table = TestTable()
grid.SetTable(table, True)
for x in range(12):
grid.SetColLabelValue(x, repr(x+1))
grid.SetColSize(x, 80)
row_labels =
['A','B','C','D','E','F','G','H']
for x in range(8):
grid.SetRowSize(x,50)
grid.SetRowLabelValue(x, row_labels[x])
grid.SetColLabelAlignment(wx.ALIGN_LEFT,
wx.ALIGN_BOTTOM)
current_view=[]
for x in range(96):
current_view.append((ph[x]))
table.SetValue(line_to_96plate[x][0],line_to_96plate[x][1],
'a')
self.CreateStatusBar() # status bar at bottom
filemenu = wx.Menu()
filemenu.Append(ID_OPEN, "&Open",
" Open ")
filemenu.AppendSeparator()
filemenu.Append(ID_SAVE, "&Save",
" Save ")
filemenu.Append(ID_EXIT, "E&xit",
" Quit ")
othermenu = wx.Menu()
othermenu.Append(ID_ABOUT,
"&About", " Written by the
incredible Byron")
#othermenu.AppendSeparator()
# create it
menuBar = wx.MenuBar()
menuBar.Append(filemenu,"&File") #
add file menu to MenuBar
menuBar.Append(othermenu,"&Other")
self.SetMenuBar(menuBar) # add menubar to frame
content
wx.EVT_MENU(self, ID_ABOUT, self.OnAbout)
wx.EVT_MENU(self, ID_OPEN, self.OnOpen)
wx.EVT_MENU(self, ID_SAVE, self.OnSave)
wx.EVT_MENU(self, ID_EXIT, self.OnExit)
self.sizer2 = wx.BoxSizer(wx.HORIZONTAL)
self.buttons=[]
button_labels = ['Salt', 'Buffer',
'Precipitant1',
'Precipitant2', 'Show All']
for i in range(0,5):
self.buttons.append(wx.Button(self,
ID_BUTTON1+i,
button_labels[i]))
self.sizer2.Add(self.buttons[i],1,wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.OnClick,
self.buttons[i])
# Use some sizers to see layout options
self.sizer=wx.BoxSizer(wx.VERTICAL)
# self.sizer.Add(self.control,0,wx.EXPAND)
self.sizer.Add(self.sizer2,0,wx.EXPAND)
self.sizer.Add(grid,2,wx.EXPAND)
#Layout sizers
self.SetSizer(self.sizer)
self.SetAutoLayout(1)
self.sizer.Fit(grid)
self.Show(True)
# This is where I would like to be able to send my data
matrix into the grid
def OnClick(self, event):
print "Click! (%d)\n" % event.GetId()
table = TestTable()
for x in range(96):
table.SetValue(line_to_96plate[x][0],line_to_96plate[x][1],
'b')
def OnAbout(self,e):
d= wx.MessageDialog( self, " A cool program
\n"
" written by
Byron","About this", wx.OK)
# Create message box
d.ShowModal()
d.Destroy()
def OnExit(self,e):
self.Close(True) # close the frame
def OnOpen(self,e):
""" Open a
file"""
self.dirname = ''
dlg = wx.FileDialog(self, "Choose a
file", self.dirname, "",
"*.*", wx.OPEN)
if dlg.ShowModal() == wx.ID_OK:
self.filename=dlg.GetFilename()
self.dirname=dlg.GetDirectory()
f=open(os.path.join(self.dirname,self.filename),'r')
self.control.SetValue(f.read())
f.close()
dlg.Destroy()
#
# This saving def needs a little work
#
def OnSave(self,e):
""" Save a
file"""
self.dirname = ''
dlg = wx.FileDialog(self, "Choose a
file", self.dirname, "",
"*.*", wx.SAVE)
if dlg.ShowModal() == wx.ID_OK:
self.filename=dlg.GetFilename()
self.dirname=dlg.GetDirectory()
f=open(os.path.join(self.dirname,self.filename),'w')
self.control.SetValue(f.read())
f.close()
dlg.Destroy()
app = wx.PySimpleApp()
frame = TestFrame()
frame.Show()
app.MainLoop()
------------code end-------------------------
--
Byron DeLaBarre, Ph.D.
Stanford Medical School
650 468 5677
------------------------------------------------------------
---------
To unsubscribe, e-mail: wxPython-users-unsubscribe lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help lists.wxwidgets.org
|
Hi Robin -
Thanks for the quick reply.
I thought I was making a reference with this line:
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Grid
Table",
size=(1120,620))
grid = wx.grid.Grid(self)
table = TestTable()
<---------------
But again, my ignorance of oop might be coming through, so
maybe I
don't know how to 'make a reference' in python! When I
try this
approach, I get an AttributeError (Testframe has no
attribute 'table')
So I tried
self.table = TestTable()
immediately after the 'table=TestTable()' line.
No error, but also no result when the OnClick function is
called (the
messge prints out, but there is apparently no call to
TestTable.SetValue (using the following code)
for x in range(96):
self.table.SetValue(line_to_96plate[x][0],line_to_96plate[x]
[1],'b')
Thanks in advance, and I thought your wxPython book was
really well done.
Best -
Byron
On 5/31/06, Robin Dunn <robin alldunn.com> wrote:
> Byron DeLaBarre wrote:
>
> > The problem is that I am stuck at trying to make a
link between the
> > button widgets and the grid widget. The buttons
work, the grid works,
> > but I cannot get the buttons to talk to the grid.
>
>
> > # This is where I would like to be able to send my
data matrix into the
> > grid
> > def OnClick(self, event):
> > print "Click! (%d)\n" %
event.GetId()
> > table = TestTable()
> > for x in range(96):
> >
table.SetValue(line_to_96plate[x][0],line_to_96plate[x][1],
'b')
>
> In your __init__ you can save a reference to the table
in self, and then
> access it here with self.table.
>
> --
> Robin Dunn
> Software Craftsman
> http://wxPython.org
Java give you jitters? Relax with wxPython!
>
>
>
------------------------------------------------------------
---------
> To unsubscribe, e-mail: wxPython-users-unsubscribe lists.wxwidgets.org
> For additional commands, e-mail:
wxPython-users-help lists.wxwidgets.org
>
>
--
Byron DeLaBarre, Ph.D.
Stanford Medical School
650 468 5677
------------------------------------------------------------
---------
To unsubscribe, e-mail: wxPython-users-unsubscribe lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help lists.wxwidgets.org
|