Refreshing window

Peter Herndon wrote:

For an auto-updating monitoring application, run a timer, when it
expires check the values of the data, then update the GUI control
values. Lather, rinse, repeat. I seem to recall running across an
event specifically for that purpose (wx.EVT_UPDATE_UI). At least, I
*think* that's what it is for, I can't seem to find any documentation
on it for use in Python, but the wxWidgets reference has some stuff on
it.

Has anyone else had occasion to work on this kind of problem?

I am not sure if my situation is the same as Andrew's, but FWIW this is how
I do it.

My application is database intensive. Most of my windows are made up of
widgets (usually wx.TextCtrl) which contain data from a particular column
from a particular row from the database.

For each table used for a particular window, I create an instance of a
'table' class, and for each column in the table I create multiple instances
of a 'column' class. Each column instance has a 'data' attribute that
contains the value of that column for the current row. Every text control
must point to a specific column instance, but not every column instance
necessarily has its own text control.

It used to work as follows. When a row is 'selected' from the database, I
populate the data attribute for each column, and then loop through all the
controls on the window, telling them to refresh themselves from their
associated column instance. If the user changes the value in the control, I
update the data attribute for the relevant column, so that the database can
be updated with the new value if the user selects 'Save'.

I had a problem. If I change a data attribute for some reason other than
user input, I need to check if there is an associated text control, and if
so, refresh the value. As my screens were getting more complex, my logic was
getting more and more tortuous.

My solution was to turn the problem on its head. Now, as I create each
control, it calls a method of its associated column instance, and passes it
'self'. The column instance adds 'self' to a list, so it knows which
control(s) are linked to it. Now every time a column's data attribute is
changed, I loop through the list, and call a refresh method on each control,
passing it the data value, telling it to redraw itself (eg using
SetValue() ). This has transformed my application, as the windows now
maintain themselves.

I will give one example of how this has made my life easier. For most
database tables, I show a 'list view' (using wx.Grid), and a 'form view',
using a panel on a wx.Dialog. Initially I display the contents of the table
using the list view, using only a subset of the available columns. If the
user clicks a particular button, I display a form view of the current row,
which is laid out with controls representing all the columns. Normally the
form view overlays the list view, but if you manually move the two windows,
you can see the list view and the form view side-by-side. Now if you are in
form view, and change a value which happens to be visible on the list view,
the value on the list view changes automatically. I was quite surprised when
I saw this happening, because I had never tried to code for this in the
first place. It was just a natural consequence of my new approach.

One minor complication is that, if the user closes the form view, each
control must inform its associated column instance so that it can be deleted
from the list, otherwise it may try to refresh a control that no longer
exists. This is easy to do by trapping the Close event.

Hope this is of interest.

Frank Millman

I'm a newbie but lets see if I understand your way of maintaining the display
of data. You have a column class that linked to columns in a row of data. I
didn't explain right one instance for each column in the row. Then you have
a table class that maintains all instances of the columns class (data
items). Then you associate a text control with column instance in the table
class. So then when you need to refresh the frame you just loop table class
columns instances? What I think I did not understand is what triggered the
refresh on the grid from form view. When a change occurs (say I type
something in the control and then tab off) does some trigger fire?

John

ยทยทยท

On Wednesday 15 December 2004 04:50, Frank Millman wrote:

I am not sure if my situation is the same as Andrew's, but FWIW this is how
I do it.

My application is database intensive. Most of my windows are made up of
widgets (usually wx.TextCtrl) which contain data from a particular column
from a particular row from the database.

For each table used for a particular window, I create an instance of a
'table' class, and for each column in the table I create multiple instances
of a 'column' class. Each column instance has a 'data' attribute that
contains the value of that column for the current row. Every text control
must point to a specific column instance, but not every column instance
necessarily has its own text control.

It used to work as follows. When a row is 'selected' from the database, I
populate the data attribute for each column, and then loop through all the
controls on the window, telling them to refresh themselves from their
associated column instance. If the user changes the value in the control, I
update the data attribute for the relevant column, so that the database can
be updated with the new value if the user selects 'Save'.

I had a problem. If I change a data attribute for some reason other than
user input, I need to check if there is an associated text control, and if
so, refresh the value. As my screens were getting more complex, my logic
was getting more and more tortuous.

My solution was to turn the problem on its head. Now, as I create each
control, it calls a method of its associated column instance, and passes it
'self'. The column instance adds 'self' to a list, so it knows which
control(s) are linked to it. Now every time a column's data attribute is
changed, I loop through the list, and call a refresh method on each
control, passing it the data value, telling it to redraw itself (eg using
SetValue() ). This has transformed my application, as the windows now
maintain themselves.

I will give one example of how this has made my life easier. For most
database tables, I show a 'list view' (using wx.Grid), and a 'form view',
using a panel on a wx.Dialog. Initially I display the contents of the table
using the list view, using only a subset of the available columns. If the
user clicks a particular button, I display a form view of the current row,
which is laid out with controls representing all the columns. Normally the
form view overlays the list view, but if you manually move the two windows,
you can see the list view and the form view side-by-side. Now if you are in
form view, and change a value which happens to be visible on the list view,
the value on the list view changes automatically. I was quite surprised
when I saw this happening, because I had never tried to code for this in
the first place. It was just a natural consequence of my new approach.

One minor complication is that, if the user closes the form view, each
control must inform its associated column instance so that it can be
deleted from the list, otherwise it may try to refresh a control that no
longer exists. This is easy to do by trapping the Close event.

Hope this is of interest.

Frank Millman