Creating an empty wx.dataview.DataViewColumn

(Reposted because I miss-threaded it.)

Is there a (correct) method for creating an empty wx.dataview.DataViewColumn?

In the examples in the demo, the data for the model is always available before the wxpython DataViewColumn is instantiated. (I have an app where I don't have the data until after the control has already been displayed.)

I have tried passing empty lists (no luck!) and have fallen back on passing a row of empty strings, instantiating the control, and then selecting the (only) row and deleting it. But that seems crude.

Is there a cleaner way?

thanks,

John

John,

Not really an answer but I would be tempted to display a static text,
the same size & place as you are expecting the DataViewColumn to be,
with the text "Awaiting Data" or some appropriate alternative, and then
replace it with the control once you have some data. I think that might
be cleaner and more user friendly.

Gadget/Steve

···

On 25/08/2011 11:27 PM, John Jackson wrote:

(Reposted because I miss-threaded it.)

Is there a (correct) method for creating an empty wx.dataview.DataViewColumn?

In the examples in the demo, the data for the model is always available before the wxpython DataViewColumn is instantiated. (I have an app where I don't have the data until after the control has already been displayed.)

I have tried passing empty lists (no luck!) and have fallen back on passing a row of empty strings, instantiating the control, and then selecting the (only) row and deleting it. But that seems crude.

Is there a cleaner way?

thanks,

John

Is the problem that you do not know how many columns there will be or is it just that there is no data to be displayed yet? For the former you should be able to set up your columns at any time. For the latter I think you can just return 0 from the model's GetCount method until you have data.

···

On 8/25/11 3:27 PM, John Jackson wrote:

(Reposted because I miss-threaded it.)

Is there a (correct) method for creating an empty wx.dataview.DataViewColumn?

In the examples in the demo, the data for the model is always available before the wxpython DataViewColumn is instantiated. (I have an app where I don't have the data until after the control has already been displayed.)

--
Robin Dunn
Software Craftsman

I know the columns and have been setting them up; it's the data isn't available yet.

But over-riding the GetCount method until the data is set seems even hokey-ier than deleting a fake row. How would I know that the count shouldn't be zero, if the user were able to delete the data by some mechanism?

The most natural thing to me would be to pass either an empty list or an empty list of lists.

Can you give or figure out how to do this with the sample (DVC_IndexListModel), so that a button can be used to set the data?

The DataViewListCtrl does work this way, as its data can be added later. Perhaps I need to look under the covers and see how it is doing it, as it is (according to the docs) a wrapper for DataViewCtrl.

Looking at the DVC_IndexListModel, I can see that GetCount would return 0 if self.data was ; though the example
has

   def GetColumnCount(self):
       return len(self.data[0])

which in't going to work very well if self.data = .

Perhaps there's a better way to return the column count. (An attribute set in the instantiation, or as columns are added?)

BTW: the only reason I am doing is this, is that the DataViewListCtrl sample (DVC_ListCtrl) only sorts on the first column; I don't know if this is a bug or by design. Perhaps it's a bug, as the other column headers show the arrows claiming they are sorting but they actually aren't.

···

On Aug 26, 2011, at 10:26 AM, Robin Dunn wrote:

On 8/25/11 3:27 PM, John Jackson wrote:

(Reposted because I miss-threaded it.)

Is there a (correct) method for creating an empty wx.dataview.DataViewColumn?

In the examples in the demo, the data for the model is always available before the wxpython DataViewColumn is instantiated. (I have an app where I don't have the data until after the control has already been displayed.)

Is the problem that you do not know how many columns there will be or is it just that there is no data to be displayed yet? For the former you should be able to set up your columns at any time. For the latter I think you can just return 0 from the model's GetCount method until you have data.

--
Robin Dunn
Software Craftsman
http://wxPython.org

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

I worked with the demo, and was able to get this to work:

I modified the init for the model to be passed the number of columns in the model, and to handle no data:

class TestModel(dv.PyDataViewIndexListModel):
    def __init__(self, data, log, defaultcolumns):
        if data:
            rowcount = len(data)
        else:
            rowcount = 0
# dv.PyDataViewIndexListModel.__init__(self, len(data))
        dv.PyDataViewIndexListModel.__init__(self, rowcount)
        self.data = data
        self.log = log
        self.defaultcolumns = defaultcolumns

I modified OnAddRow to test if the model had data, and if not, use a curcount of 0:

    def OnAddRow(self, evt):
        # Add some bogus data to a new row in the model
        self.log.write("OnAddRow\n")
        if self.model.data:
            id = len(self.model.data) + 1
        else:
            id = 1
        value = [str(id),
                 'new artist %d' % id,
                 'new title %d' % id,
                 'genre %d' % id]
        self.model.AddRow(value)

(this fixes an out by one bug that I reported as wxTrac has been migrated to GitHub Issues - wxWidgets )

In the model, I changed AddRow to create the data if it doesn't exist:

    def AddRow(self, value):
        if not self.data:
            self.data = [value]
        else:
            # update data structure
            self.data.append(value)
        # notify views
        self.RowAppended()

I modified GetColumnCount:

    # Report how many columns this model provides data for.
    def GetColumnCount(self):
        if self.data:
            self.log.write('GetColumnCount: %d' % len(self.data[0]))
            return len(self.data[0])
        else:
            self.log.write('GetColumnCount: Default %d' % self.defaultcolumns)
            return self.defaultcolumns

I modified GetCount in case data was None:

    # Report the number of rows in the model
    def GetCount(self):
        if self.data:
            rowcount = len(self.data)
        else:
            rowcount = 0
        self.log.write('GetCount: %d' % rowcount)
        return rowcount

When the model is instantiated:

        # Create an instance of our simple model...
        if model is None:
            self.model = TestModel(data, log, defaultcolumns=4)
        else:
            self.model = model

I then instantiate without any data:

# win = TestPanel(nb, log, data=musicdata)
    win = TestPanel(nb, log, data=None)
    return win

This works.

However, deleting rows doesn't update the view(s). Adding rows does. I reported this as wxTrac has been migrated to GitHub Issues - wxWidgets .

···

On Aug 26, 2011, at 1:04 PM, John Jackson wrote:

I know the columns and have been setting them up; it's the data isn't available yet.

But over-riding the GetCount method until the data is set seems even hokey-ier than deleting a fake row. How would I know that the count shouldn't be zero, if the user were able to delete the data by some mechanism?

The most natural thing to me would be to pass either an empty list or an empty list of lists.

Can you give or figure out how to do this with the sample (DVC_IndexListModel), so that a button can be used to set the data?

The DataViewListCtrl does work this way, as its data can be added later. Perhaps I need to look under the covers and see how it is doing it, as it is (according to the docs) a wrapper for DataViewCtrl.

Looking at the DVC_IndexListModel, I can see that GetCount would return 0 if self.data was ; though the example
has

  def GetColumnCount(self):
      return len(self.data[0])

which in't going to work very well if self.data = .

Perhaps there's a better way to return the column count. (An attribute set in the instantiation, or as columns are added?)

BTW: the only reason I am doing is this, is that the DataViewListCtrl sample (DVC_ListCtrl) only sorts on the first column; I don't know if this is a bug or by design. Perhaps it's a bug, as the other column headers show the arrows claiming they are sorting but they actually aren't.

On Aug 26, 2011, at 10:26 AM, Robin Dunn wrote:

On 8/25/11 3:27 PM, John Jackson wrote:

(Reposted because I miss-threaded it.)

Is there a (correct) method for creating an empty wx.dataview.DataViewColumn?

In the examples in the demo, the data for the model is always available before the wxpython DataViewColumn is instantiated. (I have an app where I don't have the data until after the control has already been displayed.)

Is the problem that you do not know how many columns there will be or is it just that there is no data to be displayed yet? For the former you should be able to set up your columns at any time. For the latter I think you can just return 0 from the model's GetCount method until you have data.

--
Robin Dunn
Software Craftsman
http://wxPython.org

As you've discovered with your modifications to the sample mentioned in the other message, a model does not have to always use a list to hold the data. It is intended to be a completely independent interface between the view and whatever data it is displaying. The use of a list in the example is just that, an example, or you could think of it as an implementation detail. From the perspective of the DVC it is almost totally irrelevant how the model is implemented, only that it does implement the required interface.

···

On 8/26/11 1:04 PM, John Jackson wrote:

I know the columns and have been setting them up; it's the data isn't available yet.

But over-riding the GetCount method until the data is set seems even hokey-ier than deleting a fake row. How would I know that the count shouldn't be zero, if the user were able to delete the data by some mechanism?

The most natural thing to me would be to pass either an empty list or an empty list of lists.

Can you give or figure out how to do this with the sample (DVC_IndexListModel), so that a button can be used to set the data?

--
Robin Dunn
Software Craftsman