[chimera-dev] Programming a Table
Eric Pettersen
pett at cgl.ucsf.edu
Wed Nov 3 11:23:47 PDT 2010
On Nov 3, 2010, at 8:22 AM, Elisabeth Ortega wrote:
> Dear all,
>
> I'm trying to do a script that shows in a table an array of numerical
> values.
> One little script that shows what I'm trying to do is:
>
> from chimera import runCommand as run
>
> run("sel")
> b=[]
> for a in chimera.selection.currentAtoms():
> b=a.serialNumber
>
> from CGLtk.Table import SortableTable
>
> t=SortableTable(b)
> t.addColumn("serial", "Serial", format=None)
> t.setData(b)
> t.launch()
>
> With this little script I'm trying to show in a column of the table
> the
> serial number of the atoms of my system.
Hi Elisabeth,
You've done a lot of things right here, but a few important things
wrong. One is that a Table can't be created in isolation; it has to
be part of a window. The simplest way to create a window is to use
the ModelessDialog class from chimera.baseDialog, like this:
from chimera.baseDialog import ModelessDialog
class MyDialog(ModelessDialog):
def fillInUI(self, parent):
# code to create table in here...
MyDialog()
[FYI, it's a "modeless" dialog because the user can interact with
other parts of Chimera while the dialog is shown (as opposed to a
"modal" dialog where the user must respond to it before doing anything
else in Chimera)]
The second problem in your code is that the first argument to
SortableTable should be the window or frame that it is to be placed
in. The "parent" argument to the fillInUI method above is the frame
in the dialog window that widgets (like your SortableTable) should be
placed in. So the code to create the table is:
t = SortableTable(parent)
The third problem with the code is that the argument to the setData
method should be a list of some sort but your code does a
"b=a.serialNumber" which makes b an integer, not a list. Another
problem is that the arguments to addColumn are the column title and
how to get the data value from an item, the latter of which should
either be an attribute name or a function that takes an item as its
argument. Since you are supplying a list of integers, the addColumn
call would be:
t.addColumn("Serial", int, format="%d")
or:
t.addColumn("Serial", str)
Both 'int' and 'str' are Python built-in functions for conversion to
integer or string.
The final problem with the code is that you need to call the grid()
method on the table so that it gets shown (there are row/column
arguments to grid() for positioning widgets relative to each other in
a single frame, but since you only have one widget [the table] you can
call grid() with no arguments).
The last thing, which isn't an error per se, is that I think it would
be better if the data given to the table were a list of atoms, rather
than a list of atom serial numbers. That way the table could display
additional columns of information (such as atom name) rather than
being restricted to just showing serial numbers.
Here's what I think your code should look like:
import chimera
from chimera.baseDialog import ModelessDialog
class TableDialog(ModelessDialog):
def fillInUI(self, parent):
from CGLtk.Table import SortableTable
t = SortableTable(parent)
# str(atom) will return something like "ALA 59 A", so use str()
func...
t.addColumn("Name", str)
t.addColumn("Serial", "serialNumber", format="%d")
from chimera import runCommand as run
run("sel")
t.setData(chimera.selection.currentAtoms())
t.launch()
# the 'sticky' arg controls resize behavior,
# with "nsew" the table will enlarge (or shrink)
# as the dialog is resized
t.grid(sticky="nsew")
TableDialog()
Finally, there is more detail about how ModelessDialogs work in the
"Extension-Specific User Interface" programmer's example at Example
FrameSet
--Eric
Eric Pettersen
UCSF Computer Graphics Lab
http://www.cgl.ucsf.edu
> But when I execute that, I got a
> message in the Python Shell that says:
>
> Traceback (most recent call last):
> File "/home/eortega/intento-tabla.py", line 11, in <module>
> t=SortableTable(b)
> File "CHIMERA/share/CGLtk/Table.py", line 489, in __init__
> File "CHIMERA/lib/python2.5/lib-tk/Tkinter.py", line 2442, in
> __init__
> Widget.__init__(self, master, 'frame', cnf, {}, extra)
> File "CHIMERA/lib/python2.5/lib-tk/Tkinter.py", line 1923, in
> __init__
> BaseWidget._setup(self, master, cnf)
> File "CHIMERA/lib/python2.5/lib-tk/Tkinter.py", line 1901, in _setup
> self.tk = master.tk
> AttributeError: 'int' object has no attribute 'tk'
>
> And I don't understand it. How can I build successfully my table?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://plato.cgl.ucsf.edu/pipermail/chimera-dev/attachments/20101103/25001d16/attachment.html>
More information about the Chimera-dev
mailing list