Skip to content

Instantly share code, notes, and snippets.

@Bouni
Last active August 6, 2024 07:28
Show Gist options
  • Save Bouni/562d62cfbfa1e5f03523396d79d389f0 to your computer and use it in GitHub Desktop.
Save Bouni/562d62cfbfa1e5f03523396d79d389f0 to your computer and use it in GitHub Desktop.
import wx
import wx.dataview as dv
import re
import random
def natural_sort_key(s):
"""Return a tuple that can be used for natural sorting."""
return [
int(text) if text.isdigit() else text.lower()
for text in re.split("([0-9]+)", s)
]
class PartListDataModel(dv.PyDataViewModel):
def __init__(self):
super(PartListDataModel, self).__init__()
self.data = [
["C1", "33P", "C_0603_1608Metric", "C1663", "187154"],
["C2", "2.2u", "C_1206_3216Metric", "C50254", "22975"],
["C3", "10n", "C_0603_1608Metric", "C57112", "536073"],
["C4", "10u", "C_0603_1608Metric", "C19702", "879880"],
["D1", "LTE-4206", "LED_D3.0mm_Clear", "", ""],
["F1", "1A", "Fuse_1206_3216Metric", "C369159", "28290"],
["FB1", "600 @ 600MHz", "L_0805_2012Metric", "C1017", "53369"],
["J1", "Conn_01x01_Female", "Pin_D1.0mm_L10.0mm", "", ""],
["J2", "Conn_01x01_Female", "Pin_D1.0mm_L10.0mm", "", ""],
["L1", "15uH", "L_Sumida_CDMC6D28_7.25x6.5mm", "C182182", "2510"],
["Q1", "SFH 309 FA-5/6", "LED_D3.0mm_IRBlack", "", ""],
["Q2", "AO3400A", "SOT-23", "C20917", "14806"],
["R1", "10k", "R_0603_1608Metric", "C25804", "5135918"],
["R2", "910", "R_0603_1608Metric", "C351623", "3300"],
["R3", "100", "R_0603_1608Metric", "C22775", "802960"],
["R4", "100", "R_0603_1608Metric", "C22775", "802960"],
["R5", "10k", "R_0603_1608Metric", "C25804", "5135918"],
["R7", "100k", "R_0603_1608Metric", "C25803", "765889"],
["R8", "18k", "R_0603_1608Metric", "C25961", "6002"],
["R9", "750", "R_0603_1608Metric", "C23241", "25248"],
["R10", "750", "R_0603_1608Metric", "C23241", "25248"],
["U1", "mh-et-live-minikit", "MH-ET LIVE MiniKit", "", ""],
["U2", "LMR54410", "SOT-23-6", "", "2484"],
["U3", "LMV7235M7X", "SOT-353_SC-70-5", "C202268", "385"],
]
def GetColumnCount(self):
return 5
def GetColumnType(self, col):
return "string"
def GetChildren(self, parent, children):
if not parent:
for row in self.data:
children.append(self.ObjectToItem(row))
return len(self.data)
return 0
def IsContainer(self, item):
return not item
def GetParent(self, item):
return dv.NullDataViewItem
def GetValue(self, item, col):
row = self.ItemToObject(item)
return row[col]
def SetValue(self, value, item, col):
row = self.ItemToObject(item)
row[col] = value
return True
def Compare(self, item1, item2, column, ascending):
"""Override to implement natural sorting."""
val1 = self.GetValue(item1, column)
val2 = self.GetValue(item2, column)
key1 = natural_sort_key(val1)
key2 = natural_sort_key(val2)
if ascending:
return (key1 > key2) - (key1 < key2)
else:
return (key2 > key1) - (key2 < key1)
def AddEntry(self, item):
"""Method to add a new entry to the data model."""
self.data.append(item)
self.ItemAdded(dv.NullDataViewItem, self.ObjectToItem(item))
def ModifyEntry(self, index, item):
"""Method to modify a random entry in the data model."""
if not self.data:
return
item = self.data[index]
item[1] += " (Modified)"
item[2] += " (Modified)"
self.ItemChanged(self.ObjectToItem(item))
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="DataViewCtrl Example with Natural Sort")
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.dvc = dv.DataViewCtrl(
panel, style=wx.BORDER_THEME | dv.DV_ROW_LINES | dv.DV_VERT_RULES
)
self.model = PartListDataModel()
self.dvc.AssociateModel(self.model)
col1 = self.dvc.AppendTextColumn(
"Reference", 0, width=150, mode=dv.DATAVIEW_CELL_EDITABLE
)
col2 = self.dvc.AppendTextColumn(
"value", 1, width=250, mode=dv.DATAVIEW_CELL_EDITABLE
)
col3 = self.dvc.AppendTextColumn(
"footprint", 2, width=250, mode=dv.DATAVIEW_CELL_EDITABLE
)
col4 = self.dvc.AppendTextColumn(
"lcsc", 3, width=250, mode=dv.DATAVIEW_CELL_EDITABLE
)
col5 = self.dvc.AppendTextColumn(
"stock", 4, width=250, mode=dv.DATAVIEW_CELL_EDITABLE
)
col1.SetSortable(True)
col2.SetSortable(True)
col3.SetSortable(True)
col4.SetSortable(True)
col5.SetSortable(True)
add_button = wx.Button(panel, label="Add Entry")
add_button.Bind(wx.EVT_BUTTON, self.OnAddEntry)
modify_button = wx.Button(panel, label="Modify Random Entry")
modify_button.Bind(wx.EVT_BUTTON, self.OnModifyEntry)
sizer.Add(self.dvc, 1, wx.EXPAND)
sizer.Add(add_button, 0, wx.ALIGN_CENTER | wx.ALL, 5)
sizer.Add(modify_button, 0, wx.ALIGN_CENTER | wx.ALL, 5)
panel.SetSizer(sizer)
self.SetSize((1200, 800))
self.Centre()
def OnAddEntry(self, event):
"""Event handler for adding a new entry."""
self.model.AddEntry(["U99", "asdfgh", "SOT-23", "C123456", "99"])
def OnModifyEntry(self, event):
"""Event handler for modifying a random entry."""
self.model.ModifyEntry(7, ["J1", "Conn_01x01_Female", "Pin_D1.0mm_L10.0mm", "", "123"])
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame()
frame.Show()
return True
if __name__ == "__main__":
app = MyApp(False)
app.MainLoop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment