I found a comment in an issue raised in the wxWidgets GitHub repository which said that in order to use the generic wxDataViewListCtrl
on GTK, you would have to build wxWidgets using the configure
option --disable-nativedvc
. If you succeeded in doing that, you would then need to produce a custom build of wxPython in order to interface with it.
Below is a very simplified example that changes the background colour of alternate rows, which does work in the native version (I am using wxPython 4.2.1 gtk3 (phoenix) wxWidgets 3.2.4 + Python 3.12.3 + Linux Mint 22). I don’t know how to implement sorting by multiple columns.
import wx
import wx.dataview as dv
def getData(num_rows, num_cols):
data = []
for r in range(num_rows):
values = []
for c in range(num_cols):
value = f"Item {r + 1},{c + 1}"
values.append(value)
data.append(values)
return data
class ColourModel(dv.DataViewIndexListModel):
def __init__(self, data):
dv.DataViewIndexListModel.__init__(self, len(data))
self.data = data
# This method is called to provide the data object for a
# particular row,col
def GetValueByRow(self, row, col):
return self.data[row][col]
# This method is called when the user edits a data item in the view.
def SetValueByRow(self, value, row, col):
self.data[row][col] = value
return True
# Report how many columns this model provides data for.
def GetColumnCount(self):
return len(self.data[0])
# Report the number of rows in the model
def GetCount(self):
return len(self.data)
# Called to check if non-standard attributes
# should be used in the cell at (row, col)
# Note: These settings are not used for cells with None values
def GetAttrByRow(self, row, col, attr):
if row % 2 == 0:
attr.SetBackgroundColour('#D0F0A0')
else:
attr.SetBackgroundColour('#A0D0E0')
return True
class TestFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, title="Coloured Rows")
self.SetSize((340, 260))
style = dv.DV_HORIZ_RULES | dv.DV_VERT_RULES
self.dvc = dv.DataViewCtrl(self, style=style)
main_sizer = wx.BoxSizer(wx.VERTICAL)
main_sizer.Add(self.dvc, 1, wx.EXPAND, 0)
self.SetSizer(main_sizer)
self.Layout()
self.num_rows = 8
self.num_cols = 4
data = getData(self.num_rows, self.num_cols)
self.displayData(data)
def displayData(self, data):
self.model = ColourModel(data)
self.dvc.AssociateModel(self.model)
for c in range(self.num_cols):
label = f"Col-{c+1}"
renderer = dv.DataViewTextRenderer()
col = dv.DataViewColumn(label, renderer, c)
self.dvc.AppendColumn(col)
app = wx.App()
frame = TestFrame(None)
frame.Show()
app.MainLoop()