0

I'm using wx.ListCtrl for live report in my app, and there will be continuous status updating including inserting a new row when a task starts and deleting related rows when the tasks end. Since the list gets sorted every now and then, you cannot simply delete the rows by the rowid you started with. Although you can assign a unique id using SetItemData, and that way you know exactly which row to delete when a task is done, there does NOT seem to be any method related to deleting a row by that unique id, not even a method to get rowid by unique id, and the only method I found is GetItemData, which will return the unique id for a certain row.

So the only way came to my mind is to iterate all rows checking their unique ids and compares it against the given id, if it matches then delete that row. But this sounds way too clumsy, so is there a better way to delete a specific row after sorting?

4

2 回答 2

0

If you can upgrade your wxPython to the 2.9.x series then there is a simple answer - use a DataViewListCtrl - in that the display reflects your data rather than actually containing the data. As a result if your data model changes due to a data item, (line), being deleted then your display will loose that line regardless of how the display is sorted. If you can't then I suspect that you will have to tag lines with a unique id and then find them for deletion.

If you need to do the latter I would suggest having a, possibly hidden, RowID column containing your unique ID and either a dictionary that you maintain with the subprocess PID as the key and the unique ID as the value or a function that maps the process id to the unique row ID.

Obviously adding the new row on the process create is not a problem, just remember to include your unique ID. When your process ends get the row ID and do something like:

def FindRow(ID):
   """ Find the row that matches the ID """
   match = None
   for index in range(self.TheGrid.GetNumberRows()):
      if self.TheGrid.GetCellValue(index, IdColNo):
         match = index
         break
   return match

       # In your process end handler
       Line = FindRow(GetID(pid))
       if (Line): 
            self.TheGrid.DeleteRows(Line, 1)
于 2013-08-15T07:23:50.433 回答
0

I ended up using ObjectListView to do the job. Basically you build an index for your objects in the list, and then you are able to operate on any row you want. It's way more convenient than wx.ListCtrl

于 2016-11-28T03:27:22.977 回答