How to increase performance of wx.grid object that has 5,000,0000 cells and uses various background colors on each cell?

I have a wx.grid object that has 5,000,0000 cells and uses various background colors on each cell. Scrolling up and down is too slow, and the overall performance of application is very poor. I have looked at the wxpython demo, there is a GridHugeTable example, it is fast but all cells are read only.

Is it possible to make the GridHugeTable’s cells editable (non-read-only)?

Hi Steve,

···

On Thu, Jan 16, 2014 at 4:37 PM, steve oslocourse@gmail.com wrote:

I have a wx.grid object that has 5,000,0000 cells and uses various background colors on each cell. Scrolling up and down is too slow, and the overall performance of application is very poor. I have looked at the wxpython demo, there is a GridHugeTable example, it is fast but all cells are read only.

Is it possible to make the GridHugeTable’s cells editable (non-read-only)?

Of course you can. Just open the script up and remove or comment out the following line:

grid.SetReadOnly(5,5, True)

Note that the example you are talking about is using a virtual grid. That is definitely what you want to do for large tables.

  • Mike

Mike Driscoll

Blog: http://blog.pythonlibrary.org

Could you please explain how GridHugeTable works? Why is it faster than the normal grid? What is the tablebase and how does it work?

···

On Friday, January 17, 2014 12:42:23 AM UTC+2, Mike Driscoll wrote:

Hi Steve,

On Thu, Jan 16, 2014 at 4:37 PM, steve osloc...@gmail.com wrote:

I have a wx.grid object that has 5,000,0000 cells and uses various background colors on each cell. Scrolling up and down is too slow, and the overall performance of application is very poor. I have looked at the wxpython demo, there is a GridHugeTable example, it is fast but all cells are read only.

Is it possible to make the GridHugeTable’s cells editable (non-read-only)?

Of course you can. Just open the script up and remove or comment out the following line:

grid.SetReadOnly(5,5, True)

Note that the example you are talking about is using a virtual grid. That is definitely what you want to do for large tables.

  • Mike

Mike Driscoll

Blog: http://blog.pythonlibrary.org

By the way, I comment out grid.SetReadOnly(5,5, True), but cells are still red-only.

···

On Friday, January 17, 2014 12:49:24 AM UTC+2, steve wrote:

Could you please explain how GridHugeTable works? Why is it faster than the normal grid? What is the tablebase and how does it work?

On Friday, January 17, 2014 12:42:23 AM UTC+2, Mike Driscoll wrote:

Hi Steve,

On Thu, Jan 16, 2014 at 4:37 PM, steve osloc...@gmail.com wrote:

I have a wx.grid object that has 5,000,0000 cells and uses various background colors on each cell. Scrolling up and down is too slow, and the overall performance of application is very poor. I have looked at the wxpython demo, there is a GridHugeTable example, it is fast but all cells are read only.

Is it possible to make the GridHugeTable’s cells editable (non-read-only)?

Of course you can. Just open the script up and remove or comment out the following line:

grid.SetReadOnly(5,5, True)

Note that the example you are talking about is using a virtual grid. That is definitely what you want to do for large tables.

  • Mike

Mike Driscoll

Blog: http://blog.pythonlibrary.org

Instead of reading all the data it only reads what is displayed.

Check out:
http://wxpython.org/Phoenix/docs/html/grid.GridTableBase.html

And there is quit a bit on the wiki:
http://wiki.wxpython.org/wxGrid

Werner

···

On 16/01/2014 23:49, steve wrote:

Could you please explain how GridHugeTable works? Why is it faster than the normal grid? What is the tablebase and how does it work?

Hi,
I used GridTableBase and a dictionary to store the cell contents. Dictionary is like:

self.data = {(0,0):“cell_content_1”, (0,1):“cell_content_2”, …}

Each dictionary key is a (row,column) tuple and values store the content of each cell
There are 5,000,000 cells, therefore the dictionary has 5,000,000 elements.

But the GUI is still too slow :frowning: How to make it faster?

···

On Friday, January 17, 2014 10:34:03 AM UTC+2, werner wrote:

On 16/01/2014 23:49, steve wrote:

Could you please explain how GridHugeTable works? Why is it faster
than the normal grid? What is the tablebase and how does it work?

Instead of reading all the data it only reads what is displayed.

Check out:

http://wxpython.org/Phoenix/docs/html/grid.GridTableBase.html

And there is quit a bit on the wiki:

http://wiki.wxpython.org/wxGrid

Werner

Your description is way too vague. What, exactly, is slow? Are you
running 32-bit Python or 64-bit Python? Have you checked how much
RAM you are using? A 5M element dictionary containing strings could
be hundreds of megabytes. If you’re short on memory, you could be
thrashing.

···

steve wrote:

    I used [GridTableBase](http://www.google.com/url?q=http%3A%2F%2Fwxpython.org%2FPhoenix%2Fdocs%2Fhtml%2Fgrid.GridTableBase.html&sa=D&sntz=1&usg=AFQjCNFuN-peGAHIJS8vz8H04P126kil-w) and a dictionary to store

the cell contents. Dictionary is like:

    self.data = {(0,0):"cell_content_1", (0,1):"cell_content_2",

…}

    Each dictionary key is a (row,column) tuple and values store the

content of each cell

    There are 5,000,000 cells, therefore the dictionary has

5,000,000 elements.

    But the GUI is still too slow :( How to make it faster?
-- Tim Roberts, Providenza & Boekelheide, Inc.

timr@probo.com

Is there a reason I am not aware of why a user who is not Commander Data would ever want to look at a table with 5,000,000 cells? That’s, for example, 20 columns across by 250,000 rows. If they could fit 50 rows on one large monitor, that means they would have to hit page down 5,000 times to scan through the table. Oh, but they’ll just use Find to find the cell(s)?..well then, maybe you could just provide that from the start and just show a small sample of the table at one time, like 1-3 screen’s worth. For the part of the dataset that they are at that moment not looking for, don’t yet have that loaded in memory, but keep it in the database on the disk.

···

On Fri, Jan 17, 2014 at 2:45 PM, Tim Roberts timr@probo.com wrote:

steve wrote:

    I used [GridTableBase](http://www.google.com/url?q=http%3A%2F%2Fwxpython.org%2FPhoenix%2Fdocs%2Fhtml%2Fgrid.GridTableBase.html&sa=D&sntz=1&usg=AFQjCNFuN-peGAHIJS8vz8H04P126kil-w) and a dictionary to store

the cell contents. Dictionary is like:

    self.data = {(0,0):"cell_content_1", (0,1):"cell_content_2",

…}

    Each dictionary key is a (row,column) tuple and values store the

content of each cell

    There are 5,000,000 cells, therefore the dictionary has

5,000,000 elements.

    But the GUI is still too slow :( How to make it faster?
-- Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
Your description is way too vague.  What, exactly, is slow?  Are you

running 32-bit Python or 64-bit Python? Have you checked how much
RAM you are using? A 5M element dictionary containing strings could
be hundreds of megabytes. If you’re short on memory, you could be
thrashing.

You received this message because you are subscribed to the Google Groups “wxPython-users” group.

To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

I agree with you - 250 thousand rows. But what about 3 thousand rows and it displays only 20 at a time. Shouldn't there be a fetch as needed grid control? This would help the performance and still allow 3000 rows.

Johnf

···

On 01/17/2014 12:13 PM, C M wrote:

Is there a reason I am not aware of why a user who is not Commander Data would ever want to look at a table with 5,000,000 cells? That's, for example, 20 columns across by 250,000 rows. If they could fit 50 rows on one large monitor, that means they would have to hit page down 5,000 times to scan through the table. Oh, but they'll just use Find to find the cell(s)?...well then, maybe you could just provide that from the start and just show a small sample of the table at one time, like 1-3 screen's worth. For the part of the dataset that they are at that moment not looking for, don't yet have that loaded in memory, but keep it in the database on the disk.

On Fri, Jan 17, 2014 at 2:45 PM, Tim Roberts <timr@probo.com > <mailto:timr@probo.com>> wrote:

    steve wrote:

    I used GridTableBase
    <Weiterleitungshinweis;
    and a dictionary to store the cell contents. Dictionary is like:

    self.data = {(0,0):"cell_content_1", (0,1):"cell_content_2", ...}

    Each dictionary key is a (row,column) tuple and values store the
    content of each cell
    There are 5,000,000 cells, therefore the dictionary has 5,000,000
    elements.

    But the GUI is still too slow :frowning: How to make it faster?

    Your description is way too vague. What, exactly, is slow? Are
    you running 32-bit Python or 64-bit Python? Have you checked how
    much RAM you are using? A 5M element dictionary containing
    strings could be hundreds of megabytes. If you're short on
    memory, you could be thrashing.

    -- Tim Roberts,timr@probo.com <mailto:timr@probo.com>
    Providenza & Boekelheide, Inc.

    -- You received this message because you are subscribed to the Google
    Groups "wxPython-users" group.
    To unsubscribe from this group and stop receiving emails from it,
    send an email to wxpython-users+unsubscribe@googlegroups.com
    <mailto:wxpython-users%2Bunsubscribe@googlegroups.com>.
    For more options, visit https://groups.google.com/groups/opt_out.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Yes, and as I understand it, there is. That's what's recommend to use the
virtual table. There is an example in the demo with 10,000 rows and, it
says, 100 million cells. (which now that I think about it, makes me wonder
what the issue is for the OP if it works so fluidly on my clunky old
laptop...?)

···

On Fri, Jan 17, 2014 at 7:34 PM, John Fabiani <fabiani.john@gmail.com>wrote:

I agree with you - 250 thousand rows. But what about 3 thousand rows
and it displays only 20 at a time. Shouldn't there be a fetch as needed
grid control? This would help the performance and still allow 3000 rows.

C M wrote:

    I agree with you - 250 thousand rows. But what about 3 thousand
    rows and it displays only 20 at a time. Shouldn't there be a fetch
    as needed grid control? This would help the performance and still
    allow 3000 rows.

Yes, and as I understand it, there is. That's what's recommend to use
the virtual table. There is an example in the demo with 10,000 rows
and, it says, 100 million cells. (which now that I think about it,
makes me wonder what the issue is for the OP if it works so fluidly on
my clunky old laptop...?)

Well, that sample generates the cell values on the fly instead of loading them from some data source, so it does cheat a little bit. But that is really the point of that sample, to show the improvement you get by implementing your own grid table and only loading and giving the view the data it needs to display at the moment instead of pre-loading all of the data into the grid at the start.

For a real application with a real data source you can accomplish much the same benefits by implementing a grid table that best optimizes fetching and putting data from your specific data source, balancing speed and memory utilization with some sort of caching or pre-fetch. Those details will be specific to the particular data source, so it is up to you to implement that part.

···

On Fri, Jan 17, 2014 at 7:34 PM, John Fabiani <fabiani.john@gmail.com > <mailto:fabiani.john@gmail.com>> wrote:

--
Robin Dunn
Software Craftsman

Dear experts,
I don’t know why but my GUI started to work fast. Maybe the PC was low on memory the first time I tried (?).
My remaining questions are:
1- Should we always use GridTableBase and a virtual table for wx.grid objects (because it makes the grid faster)?
2- Is it OK to use a dictionary to keep the grid data of virtual table as below:

     self.data = {(0,0):"cell_content_1", (0,1):"cell_content_2",

…}

Or do you recommend a list, tuple or a set instead of a dictonary? Which one is fastest?

Best Regards

···

On Saturday, January 18, 2014 11:38:35 PM UTC+2, Robin Dunn wrote:

C M wrote:

On Fri, Jan 17, 2014 at 7:34 PM, John Fabiani <fabian...@gmail.com > > > mailto:fabian...@gmail.com> wrote:

I agree with you - 250 thousand rows.  But what about 3 thousand
rows and it displays only 20 at a time.  Shouldn't there be a fetch
as needed grid control?  This would help the performance and still
allow 3000 rows.

Yes, and as I understand it, there is. That’s what’s recommend to use

the virtual table. There is an example in the demo with 10,000 rows

and, it says, 100 million cells. (which now that I think about it,

makes me wonder what the issue is for the OP if it works so fluidly on

my clunky old laptop…?)

Well, that sample generates the cell values on the fly instead of
loading them from some data source, so it does cheat a little bit. But
that is really the point of that sample, to show the improvement you get
by implementing your own grid table and only loading and giving the view
the data it needs to display at the moment instead of pre-loading all of
the data into the grid at the start.

For a real application with a real data source you can accomplish much
the same benefits by implementing a grid table that best optimizes
fetching and putting data from your specific data source, balancing
speed and memory utilization with some sort of caching or pre-fetch.
Those details will be specific to the particular data source, so it is
up to you to implement that part.


Robin Dunn

Software Craftsman

http://wxPython.org

*1*- Should we always use GridTableBase<Weiterleitungshinweis a virtual table for *wx.grid
*objects (because it makes the grid faster)?

only if the Gird is large -- there are some use-cases with smaller data
sets where it's fine to use the regular version. But I'd say of the dataset
is arbitrarily large, then yes.

*2*- Is it OK to use a dictionary to keep the grid data of virtual table as

below:

self.data = {(0,0):"cell_content_1", (0,1):"cell_content_2", ...}

Or do you recommend a list, tuple or a set instead of a dictonary? Which
one is fastest?

well, I think a list of lists is the most natural, and will be very
efficient.

A dict like that would make sense if the data in the grid is sparse -- i.e.
lots of empty cells, then you wouldn't need to store anything for the empty
ones. But if there are not very many empty cells, then a list of lists maps
well to the rectangular nature of the grid.

I wouldn't use tuples, as they are immutable, you'd need to re-create them
if anything changed. It might be OK if it's read only data, though.

as for fastest, a lis tof lists should be a bit fast, but I doubt you'd
notice -- both are order 1 access.

now that I think about it -- if you are removing rows or columns frequently
a dict might be a better choice for performance, but it would be a bit
uglier for code.

Another option -- I'd consider a numpy array -- they can be true 2-d arrays
which maps better to the grid data model. They can hold either homogenous
data types (e.g. all floats), or python objects, much like a list. Numpy
arrays would let you more naturally access the data by either rows or
columns.

Sorry -- that was a bit rambling -- but when it comes down to it the short
answer is "it depends"

-CHB

Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython

···

On Sat, Jan 18, 2014 at 1:52 PM, steve <oslocourse@gmail.com> wrote:

Just for completeness I would add to the above that you have a grid - for some value of big but generally big enough that the data
will not all fit in memory along side of your code - then you will
need to keep your data in a database or a set of files with possibly
some pre-loading i.e. if your maximum viewable number of lines &
cols on a screen is 40x40 I would consider trying to hold at least
120x120, with your view in the middle, in memory.
Gadget/Steve

···

On 19/01/14 00:58, Christopher Barker
wrote:

        On Sat, Jan 18, 2014 at 1:52 PM,

steve oslocourse@gmail.com
wrote:

1- Should we always use GridTableBase and a virtual table
for wx.grid objects (because it makes the grid
faster)?

          only if the Gird is large -- there are some use-cases

with smaller data sets where it’s fine to use the regular
version. But I’d say of the dataset is arbitrarily large,
then yes.

2 - Is it OK to use a dictionary to
keep the grid data of virtual table as below:

                                   self.data

= {(0,0):“cell_content_1”, (0,1):“cell_content_2”,
…}

            Or do you recommend a list, tuple or a set instead of a

dictonary? Which one is fastest?

          well, I think a list of lists is the most natural, and

will be very efficient.

          A dict like that would make sense if the data in the

grid is sparse – i.e. lots of empty cells, then you
wouldn’t need to store anything for the empty ones. But if
there are not very many empty cells, then a list of lists
maps well to the rectangular nature of the grid.

          I wouldn't use tuples, as they are immutable, you'd

need to re-create them if anything changed. It might be OK
if it’s read only data, though.

          as for fastest, a lis tof lists should be a bit fast,

but I doubt you’d notice – both are order 1 access.

          now that I think about it -- if you are removing rows

or columns frequently a dict might be a better choice for
performance, but it would be a bit uglier for code.

          Another option -- I'd consider a numpy array -- they

can be true 2-d arrays which maps better to the grid data
model. They can hold either homogenous data types (e.g.
all floats), or python objects, much like a list. Numpy
arrays would let you more naturally access the data by
either rows or columns.

          Sorry -- that was a bit rambling -- but when it comes

down to it the short answer is “it depends”

-CHB

big

@Steve What do you exactly mean I should keep the data in database? I shouldn’t keep the data in a dictionary if data is too big? Will it be faster than dictionary? Could you provide a sample code where the grid loads data from a database?

Best regards

···

On Sunday, January 19, 2014 10:33:06 AM UTC+2, Gadget Steve wrote:

  On 19/01/14 00:58, Christopher Barker > wrote:
        On Sat, Jan 18, 2014 at 1:52 PM, > > steve <osloc...@gmail.com> > >             wrote:

1- Should we always use GridTableBase and a virtual table
for wx.grid objects (because it makes the grid
faster)?

          only if the Gird is large -- there are some use-cases

with smaller data sets where it’s fine to use the regular
version. But I’d say of the dataset is arbitrarily large,
then yes.

2 - Is it OK to use a dictionary to
keep the grid data of virtual table as below:

                                   self.data

= {(0,0):“cell_content_1”, (0,1):“cell_content_2”,
…}

            Or do you recommend a list, tuple or a set instead of a

dictonary? Which one is fastest?

          well, I think a list of lists is the most natural, and

will be very efficient.

          A dict like that would make sense if the data in the

grid is sparse – i.e. lots of empty cells, then you
wouldn’t need to store anything for the empty ones. But if
there are not very many empty cells, then a list of lists
maps well to the rectangular nature of the grid.

          I wouldn't use tuples, as they are immutable, you'd

need to re-create them if anything changed. It might be OK
if it’s read only data, though.

          as for fastest, a lis tof lists should be a bit fast,

but I doubt you’d notice – both are order 1 access.

          now that I think about it -- if you are removing rows

or columns frequently a dict might be a better choice for
performance, but it would be a bit uglier for code.

          Another option -- I'd consider a numpy array -- they

can be true 2-d arrays which maps better to the grid data
model. They can hold either homogenous data types (e.g.
all floats), or python objects, much like a list. Numpy
arrays would let you more naturally access the data by
either rows or columns.

          Sorry -- that was a bit rambling -- but when it comes

down to it the short answer is “it depends”

-CHB

Just for completeness I would add to the above that you have a big
grid - for some value of big but generally big enough that the data
will not all fit in memory along side of your code - then you will
need to keep your data in a database or a set of files with possibly
some pre-loading i.e. if your maximum viewable number of lines &
cols on a screen is 40x40 I would consider trying to hold at least
120x120, with your view in the middle, in memory.

Gadget/Steve

Where is your data coming from?
If from a database then I would just have in self.data the
information to access the particular database information for your
grid column data, that would probably be the primary key to your
base table.
In other words keep as little data as possible in self.data to
optimize the memory usage.
Werner
P.S.
I am no expert

···

Hi Steve,

  On 18/01/2014 22:52, steve wrote:

Dear experts,

    I don't know why but my GUI started to work fast. Maybe the PC

was low on memory the first time I tried (?).

    My remaining questions are:

    **1**- Should we always use [GridTableBase](http://www.google.com/url?q=http%3A%2F%2Fwxpython.org%2FPhoenix%2Fdocs%2Fhtml%2Fgrid.GridTableBase.html&sa=D&sntz=1&usg=AFQjCNFuN-peGAHIJS8vz8H04P126kil-w) and a virtual table for **        wx.grid**objects (because it makes the grid faster)?
    **2**        - Is it OK to use a dictionary to keep the grid data of

virtual table as below:

               self.data =

{(0,0):“cell_content_1”, (0,1):“cell_content_2”, …}

    Or do you recommend a list, tuple or a set instead of a

dictonary? Which one is fastest?

:slight_smile:

Dear sirs,
I don’t understand how to make grid get its data from a database. The virtual table is a sub-class of gridlib.PyGridTableBase:

class VirtualTable(gridlib.PyGridTableBase):
def init(self, rows, cols):
gridlib.PyGridTableBase.init(self)
self.num_of_rows = rows
self.num_of_cols = cols
self.data = {}
for row in xrange(rows):
for col in xrange(cols):
self.data[(row,col)] = “cell_content_%s_%s” %(row, col)

table = VirtualTable(1000, 5000)
MainGrid_object.SetTable(table, True)

I don’t understand how the virtual table above gets the data from a database instead of a dictonary. Could you please explain?

Best regards

···

On Sunday, January 19, 2014 1:14:28 PM UTC+2, werner wrote:

Hi Steve,

  On 18/01/2014 22:52, steve wrote:

Dear experts,

    I don't know why but my GUI started to work fast. Maybe the PC

was low on memory the first time I tried (?).

    My remaining questions are:

    **1**- Should we always use [GridTableBase](http://www.google.com/url?q=http%3A%2F%2Fwxpython.org%2FPhoenix%2Fdocs%2Fhtml%2Fgrid.GridTableBase.html&sa=D&sntz=1&usg=AFQjCNFuN-peGAHIJS8vz8H04P126kil-w) and a virtual table for **        wx.grid**objects (because it makes the grid faster)?
    **2**        - Is it OK to use a dictionary to keep the grid data of

virtual table as below:

               self.data =

{(0,0):“cell_content_1”, (0,1):“cell_content_2”, …}

    Or do you recommend a list, tuple or a set instead of a

dictonary? Which one is fastest?

Where is your data coming from?

If from a database then I would just have in self.data the

information to access the particular database information for your
grid column data, that would probably be the primary key to your
base table.

In other words keep as little data as possible in self.data to

optimize the memory usage.

Werner



P.S.

I am no expert :-)

The above is NOT a virtual table as you are creating all the row,
col contents in init for a virtual grid you provide:
GetNumberRows(self) - Returns the number of rows in your data
GetNumberCols(self) - Returns the number of cols in your data
IsEmptyCell(self, row, col) - Used for space data
GetValue(self, row, col) - Return the data for a given position
usually as a string &
SetValue(self, row, col, value) - Handle the setting of a value
The mega grid example handles the first two by returning 10000 for
each, the third with false, GetValue by creating a string for that
cell and SetValue by logging the even.
If your data is in a database the first two will return respectively
the number of, (matching in the case of a query), data entries and
the maximum number of fields in an entry. The next two will be
responded to with the results from querying the database for a given
row of data, (usually cashed in some way, e.g. have a 100 records in
memory and if the request is within 20 of either end of the 100 you
have then query the DB for the 100 round that value in a separate
thread, (100 & 20 will depend on the amount of your RAM and on
the speed of your database. But if the row is outside of your 100
then display a busy message while you query the 100 based round your
row.
Set value will equate to a database record update, (obviously better
cached as well), these updates are usually only done on a row focus
change or with a timer.
Hopefully the above is some help.
Gadget/Steve

···

On 19/01/14 11:22, steve wrote:

Dear sirs,

    I don't understand how to make grid get its data from a

database. The virtual table is a sub-class of gridlib.PyGridTableBase:

              class

VirtualTable(gridlib.PyGridTableBase):

          def __init__(self, rows, cols):

              gridlib.PyGridTableBase.__init__(self)

              self.num_of_rows = rows

              self.num_of_cols = cols

              self.data = {}

              for row in xrange(rows):

                  for col in xrange(cols):

                      self.data[(row,col)] = "cell_content_%s_%s"

%(row, col)

      table = VirtualTable(1000, 5000)

      MainGrid_object.SetTable(table, True)



    I don't understand how the virtual table above gets the data

from a database instead of a dictonary. Could you please
explain?

    Best regards

must

I would have something along these lines:
method ‘loadData’: it queries the database to obtain the primary
keys of all the data you are interested in and load that into e.g.
‘self.dataKeys’ and the data is sorted in the same order as you want
to display it in the grid and it clears ‘self.dataDetails’.
method ‘GetNumberRows(self)’: override it to return the length of
‘self.dataKeys’
method ‘GetValue(self, row, col)’: override it to get the data from
the database for the row requested. In this method you use the
value of ‘row’ to obtain the primary key from ‘self.dataKeys’ and do
a query to get all the data for that row and then return data for
‘col’
You might want to optimize this with some sort of a cache for about
2 to 3 pages worth of data, in which case “GetValue” would not query
the database directly but would query your cache and if it realizes
that the data is not yet present for the ‘row’ requested then read
the database and store the data for all columns for that row in e.g.
“self.dataDetails”.
When the sort order changes call the method ‘loadData’.
When ‘DataDetails’ is getting larger then the 2 to 3 pages then
clear it and start loading it with the details requested.
That means that the above code would become something like this:
Hope this is enough to get you going. If you use for your database
sqllite with or without SQLAlchemy to access it you always create a
and I am sure someone on
the list can help with problems you run into.
Werner

···

Hi Steve,

  On 19/01/2014 12:22, steve wrote:

Dear sirs,

    I don't understand how to make grid get its data from a

database. The virtual table is a sub-class of gridlib.PyGridTableBase:

              class

VirtualTable(gridlib.PyGridTableBase):

          def __init__(self, rows, cols):

              gridlib.PyGridTableBase.__init__(self)

              self.num_of_rows = rows

              self.num_of_cols = cols

              self.data = {}

              for row in xrange(rows):

                  for col in xrange(cols):

                      self.data[(row,col)] = "cell_content_%s_%s"

%(row, col)

      table = VirtualTable(1000, 5000)

      MainGrid_object.SetTable(table, True)



    I don't understand how the virtual table above gets the data

from a database instead of a dictonary. Could you please
explain?

  class

VirtualTable(gridlib.PyGridTableBase):

      def __init__(self):

          gridlib.PyGridTableBase.__init__(self)

          self.loadData()

      def loadData(self):

          self.dataKeys = []

          ... get the primary keys from the database

      def GetNumberRows(self):

          return len(self.dataKeys)

      def GetNumberCols(self):

          return ??? the number of columns your grid will have

      def GetValue(self, row, col):

          self.getDataFromCache(row, col)

      def getDataFromCache(self, row, col):

          if we have data for row and col return it

          else get it from the database and load it into the cache

(e.g. a dict) and return it

      def getDataFromDB(self, row):

          get data for 'row' from database and load it into the

cache

  table = VirtualTable()

  MainGrid_object.SetTable(table, True)

http://wiki.wxpython.org/MakingSampleApps

I have started working on this and will let you know about the result. Using a database is more professional, and I prefer it. But I don’t understand and don’t know how the application will know when it has to fetch data from database. If the grid is too wide, it won’t fit to screen, and user will have to scroll to right to see the rest of the grid. Then the virtual table gets the data from dictionary (or database) on demand. How will I cache the necessary amount of data??

···

On Sunday, January 19, 2014 2:19:55 PM UTC+2, werner wrote:

Hi Steve,

  On 19/01/2014 12:22, steve wrote:

Dear sirs,

    I don't understand how to make grid get its data from a

database. The virtual table is a sub-class of gridlib.PyGridTableBase:

              class

VirtualTable(gridlib.PyGridTableBase):

          def __init__(self, rows, cols):

              gridlib.PyGridTableBase.__init__(self)

              self.num_of_rows = rows

              self.num_of_cols = cols

              self.data = {}

              for row in xrange(rows):

                  for col in xrange(cols):

                      self.data[(row,col)] = "cell_content_%s_%s"

%(row, col)

      table = VirtualTable(1000, 5000)

      MainGrid_object.SetTable(table, True)



    I don't understand how the virtual table above gets the data

from a database instead of a dictonary. Could you please
explain?

I would have something along these lines:

method 'loadData': it queries the database to obtain the primary

keys of all the data you are interested in and load that into e.g.
‘self.dataKeys’ and the data is sorted in the same order as you want
to display it in the grid and it clears ‘self.dataDetails’.

method 'GetNumberRows(self)': override it to return the length of

‘self.dataKeys’

method 'GetValue(self, row, col)': override it to get the data from

the database for the row requested. In this method you use the
value of ‘row’ to obtain the primary key from ‘self.dataKeys’ and do
a query to get all the data for that row and then return data for
‘col’

You might want to optimize this with some sort of a cache for about

2 to 3 pages worth of data, in which case “GetValue” would not query
the database directly but would query your cache and if it realizes
that the data is not yet present for the ‘row’ requested then read
the database and store the data for all columns for that row in e.g.
“self.dataDetails”.

When the sort order changes call the method 'loadData'.



When 'DataDetails' is getting larger then the 2 to 3 pages then

clear it and start loading it with the details requested.

That means that the above code would become something like this:



      class

VirtualTable(gridlib.PyGridTableBase):

      def __init__(self):

          gridlib.PyGridTableBase.__init__(self)

          self.loadData()



      def loadData(self):

          self.dataKeys = []

          ... get the primary keys from the database



      def GetNumberRows(self):

          return len(self.dataKeys)



      def GetNumberCols(self):

          return ??? the number of columns your grid will have



      def GetValue(self, row, col):

          self.getDataFromCache(row, col)



      def getDataFromCache(self, row, col):

          if we have data for row and col return it

          else get it from the database and load it into the cache

(e.g. a dict) and return it

      def getDataFromDB(self, row):

          get data for 'row' from database and load it into the

cache

  table = VirtualTable()

  MainGrid_object.SetTable(table, True)



Hope this is enough to get you going.  If you use for your database

sqllite with or without SQLAlchemy to access it you always create a
http://wiki.wxpython.org/MakingSampleApps and I am sure someone on
the list can help with problems you run into.

Werner