wxPython列表与网格控件使用指南
发布时间: 2025-08-17 02:04:05 阅读量: 1 订阅数: 5 

### wxPython 列表与网格控件使用指南
#### 1. 列表控件概述
列表控件是 wxPython 中用于显示信息列表的组件,相较于简单的列表框,它功能更复杂且全面。列表控件是 `wx.ListCtrl` 类的实例,有多种显示模式:
- **图标模式**:每个项目文本显示在图标下方。
- **小图标模式**:使用较小的图标。
- **列表模式**:元素按列显示,从一列底部换行到下一列顶部。
- **报告模式**:列表以多列格式显示,有列标题,每行一个项目。
列表控件的图像由图像列表管理,图像列表是一个可通过整数索引访问的图像数组,列表控件可为不同列表模式维护单独的图像列表,便于在不同模式间切换。
插入文本和图像到列表可使用以下方法:
- `InsertStringItem(index, label)`:插入文本。
- `InsertImageItem(index, imageIndex)`:插入图像。
- `InsertImageStringItem(index, label, imageIndex)`:同时插入文本和图像。
- `InsertColumn(col, heading, format="wx.LIST_FORMAT_LEFT", width=-1)`:在报告模式下添加列。添加列后,可使用 `SetStringItem(index, col, label, imageId=-1)` 向新列添加文本。
列表控件会生成多种事件,可绑定到程序操作,事件项属于 `wx.ListEvent` 类,常见事件类型包括 `EVT_LIST_INSERT_ITEM`、`EVT_LIST_ITEM_ACTIVATED` 和 `EVT_LIST_ITEM_SELECTED`。
若列表控件声明时带有 `wx.LC_EDIT_LABELS` 标志,用户选中列表项时可编辑文本,按回车键或点击控件其他位置接受编辑,按 ESC 键取消编辑。
可通过 `wx.LC_SORT_ASCENDING` 或 `wx.LC_SORT_DESCENDING` 标志对列表进行排序,这将根据字符串顺序对项目排序,在报告模式下将使用第 0 列的字符串。也可使用 `SortItems(func)` 方法创建自定义排序方法,对于报告模式的列表,`wx.lib.mixins.listctrl.ColumnSorterMixin` 混合类可让你按用户选择的列进行排序。
#### 2. 创建虚拟列表控件
当列表数据量增大时,普通列表控件可能会出现性能问题,如启动时间变长、占用大量内存。为解决这些问题,可创建虚拟列表控件。
虚拟列表控件的信息仅在需要显示项目时按需生成,避免了在自身内存空间中存储每个项目,且整个控件在启动时无需全部声明。不过,虚拟列表中列表项的检索速度可能较慢。
以下是创建虚拟列表控件的步骤:
1. **设置虚拟标志**:在初始化列表控件时,将 `wx.LC_VIRTUAL` 标志作为参数传递。通常需要通过继承 `wx.ListCtrl` 来创建虚拟列表控件,因为需要重写一些方法来填充虚拟列表。示例代码如下:
```python
class MyVirtualList(wx.ListCtrl):
def __init__(self, parent):
wx.ListCtrl.__init__(self, parent, -1,
style=wx.LC_REPORT|wx.LC_VIRTUAL)
```
2. **调用 `SetItemCount()` 方法**:在初始化过程中调用该方法,告知控件数据源中存在的数据项数量,以便设置适当的限制并管理滚动条。若数据源中的项目数量发生变化,可再次调用该方法。
3. **重写方法**:虚拟列表控件可重写父类的三个方法来确定列表控件中显示的内容。
- `OnGetItemText(item, col)`:最重要的方法,`item` 和 `col` 参数分别是要绘制的单元格的行和列,返回值是该单元格要显示的文本字符串。示例:
```python
def OnGetItemText(self, item, col):
return "Item %d, column %d" % (item, col)
```
- `OnGetItemImage(item)`:若要在某行显示图像,需重写此方法,返回值是列表控件图像列表的整数索引。若不重写,基类版本返回 -1,表示不显示图像。
- `OnGetItemAttr(item)`:若要更改某行的显示属性,可重写此方法,该方法接受行索引作为参数,返回 `wx.ListItemAttr` 类的实例,该类有多个 getter 和 setter 方法,可用于设置行的颜色、对齐方式或其他显示设置。
若虚拟列表控件所基于的数据发生变化,可使用 `RefreshItem(item)` 方法强制重绘特定行,使用 `RefreshItems(itemFrom, itemTo)` 方法重绘两个索引之间的所有行。
为优化数据源中数据项的获取,虚拟列表控件在即将显示新的数据页面时会发送 `EVT_LIST_CACHE_HINT` 事件,这使数据源有机会一次性从数据库(或其他数据源)中获取多条记录并保存,后续对这些项目的 `OnGetItemText()` 调用会比每次都从数据库获取记录快得多。
以下是一个完整的虚拟列表控件示例代码:
```python
import wx
import sys, glob, random
import data
class DataSource:
def GetColumnHeaders(self):
return data.columns
def GetCount(self):
return len(data.rows)
def GetItem(self, index):
return data.rows[index]
def UpdateCache(self, start, end):
pass
class VirtualListCtrl(wx.ListCtrl):
def __init__(self, parent, dataSource):
wx.ListCtrl.__init__(self, parent,
style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VIRTUAL)
self.dataSource = dataSource
self.Bind(wx.EVT_LIST_CACHE_HINT, self.DoCacheItems)
self.SetItemCount(dataSource.GetCount())
columns = dataSource.GetColumnHeaders()
for col, text in enumerate(columns):
self.InsertColumn(col, text)
def DoCacheItems(self, evt):
self.dataSource.UpdateCache(
evt.GetCacheFrom(), evt.GetCacheTo())
def OnGetItemText(self, item, col):
data = self.dataSource.GetItem(item)
return data[col]
def OnGetItemAttr(self, item):
return None
def OnGetItemImage(self, item):
return -1
class DemoFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1,
"Virtual wx.ListCtrl",
size=(600, 400))
self.list = VirtualListCtrl(self, DataSource())
app = wx.PySimpleApp()
frame = DemoFrame()
frame.Show()
app.MainLoop()
```
#### 3. 列表控件其他有用方法
| 方法 | 描述 |
| ---- | ---- |
| `GetViewRect()` | 返回一个 `wx.Rect`,对应于无需滚动即可跨越所有项目的最小矩形,仅在图标和小图标模式下有意义。 |
| `ScrollList(dx, dy)` | 使控件滚动,`dy` 参数是垂直像素量,`dx` 参数是水平像素量。对于图标、小图标或报告视图,单位是像素;若列表控件处于列表模式,单位是列表显示的列。 |
#### 4. 网格控件概述
网格控件是 wxPython 中最复杂和灵活的单个控件,可将表格数据以类似电子表格的网格格式显示。它允许为行和列指定标签,通过拖动网格线更改网格大小,还可单独指定每个单元格的字体和颜色属性。
大多数情况下,单元格值以简单字符串显示,但也可为任何单元格指定自定义渲染器,以不同方式显示数据,如将布尔值显示为复选框。可在表格中直接编辑网格单元格,并根据不同类型的数据使用不同类型的编辑器,还可创建自定义渲染器和编辑器,在单元格数据的显示和管理方面提供几乎无限的灵活性。网格控件还有大量鼠标和键盘事件,可捕获并用于触发应用程序中的代码。
#### 5. 创建网格控件
网格控件用于显示二维数据集,在 wxPython 中,有两种不同的机制来处理网格控件中的数据,每种机制在添加、删除和编辑数据的方式上略有不同:
- **网格控件直接管理值**:网格维护自己的数据副本,若数据量较大或应用程序已有类似网格的数据结构,这种方式可能不太方便。
- **使用网格表间接管理数据**:网格表是一个单独的类,用于存储数据并与网格控件交互以显示数据,在数据复杂、已存储在其他对象中或网格太大不宜一次性全部存储在内存中时,推荐使用网格表。
##### 5.1 创建简单网格
创建简单网格的步骤如下:
1. **导入必要模块**:
```python
import wx
import wx.grid
```
2. **创建框架和网格控件**:
```python
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Simple Grid",
size=(640, 480))
grid = wx.grid.Grid(self)
```
3. **初始化网格**:使用 `CreateGrid(numRows, numCols, selmode=wx.grid.Grid.SelectCells)` 方法,该方法应在构造函数之后直接调用,且必须在网格显示之前调用。`numRows` 和 `numCols` 参数指定网格的初始大小,`selmode` 参数指定网格中单元格的选择模式,默认值 `wx.grid.Grid.SelectCells` 表示用户选择由单个单元格组成,其他值包括 `wx.grid.Grid.SelectRows`(整行选择)和 `wx.grid.Grid.SelectionColumns`(整列选择)。
```python
grid.CreateGrid(50, 50)
```
4. **设置单元格值**:使用 `SetCellValue(row, col, s)` 方法,`row` 和 `col` 参数是要设置的单元格坐标,`s` 是要显示的字符串文本。
```python
for row in range(20):
f
```
0
0
相关推荐










