【问题标题】:Item Checking not possible with UltimateListCtrl in ULC_VIRTUAL mode在 ULC_VIRTUAL 模式下无法使用 UltimateListCtrl 进行项目检查
【发布时间】:2011-12-21 22:04:42
【问题描述】:

以下是系统和软件信息

平台:Windows XP 和 OSX Lion
Activestate Python 2.7.2
wxPython2.9-osx-cocoa-py2.7(用于 OSX)
wxPython2.9-win32-py27(适用于 Windows XP)

我正在尝试使用 ULC_VIRTUAL 和 ULC_REPORT 模式创建 UltimateListCtrl。我想知道如何在每行的第一列旁边放置一个复选框,并在用户选中该框时捕获事件。我可以在没有虚拟模式的情况下使用 UltimateListCtrl 做同样的事情。但是,在 ULC_VIRTUAL 标志打开的情况下,我不知道如何进行。以下是我创建的代码,但这仍然不允许我选中与第一列关联的框。请帮忙。

import wx
    import images
    import random
    import os, sys
from wx.lib.agw import ultimatelistctrl as ULC

class TestUltimateListCtrl(ULC.UltimateListCtrl):
    def __init__(self, parent, log):

        ULC.UltimateListCtrl.__init__(self, parent, -1, agwStyle=ULC.ULC_VIRTUAL|ULC.ULC_REPORT|ULC.ULC_SINGLE_SEL|ULC.ULC_VRULES|ULC.ULC_HRULES)
    self.SetItemCount(1000)
    self.table_fields=['First','Second','Third']
    field_index=0
        for field in self.table_fields:
        info = ULC.UltimateListItem()
        info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT | ULC.ULC_MASK_CHECK
        info._image = []
        info._format = wx.LIST_FORMAT_CENTER
        info._kind = 1      
        info._text = field
        info._font= wx.Font(13, wx.ROMAN, wx.NORMAL, wx.BOLD)
        self.InsertColumnInfo(field_index, info)
        self.SetColumnWidth(field_index,175)
        field_index += 1

    def getColumnText(self, index, col):
        item = self.GetItem(index, col)
        return item.GetText()

    def OnGetItemText(self, item, col):
        return "Item %d, Column %d" % (item,col)

    def OnGetItemColumnImage(self, item, col):
        return []

    def OnGetItemImage(self, item):
        return []

    def OnGetItemAttr(self, item):
        return None

    def OnGetItemTextColour(self, item, col):
        return None

    #def OnGetItemColumnCheck(self, item, col):
    #return True

    #def OnGetItemCheck(self, item):
    #return True

    def OnGetItemToolTip(self, item, col):
        return None

    def OnGetItemKind(self, item):
        return 1

    def OnGetItemColumnKind(self, item, col):
        if col==0:
            return self.OnGetItemKind(item)
        return 0

class TestFrame(wx.Frame):
    def __init__(self, parent, log):
        wx.Frame.__init__(self, parent, -1, "UltimateListCtrl in wx.LC_VIRTUAL mode", size=(700, 600))
        panel = wx.Panel(self, -1)
        sizer = wx.BoxSizer(wx.VERTICAL)
        listCtrl = TestUltimateListCtrl(panel, log)
        sizer.Add(listCtrl, 1, wx.EXPAND)
        panel.SetSizer(sizer)
        sizer.Layout()
        self.CenterOnScreen()
        self.Show()

if __name__ == '__main__':
    import sys
    app = wx.PySimpleApp()
    frame = TestFrame(None, sys.stdout)
    frame.Show(True)
    app.MainLoop()

顺便说一句,以下是我用来在没有虚拟模式的情况下创建相同内容的代码。在这种情况下,我可以选中每一行中第一列数据旁边的框。但是,我将处理数以万计的项目,我不能依赖加载像下面这样的项目,因为它非常慢。因此,我想使用虚拟列表,但我不知道如何在其中获得相同的功能。

import wx
import images
import random
import os, sys
from wx.lib.agw import ultimatelistctrl as ULC

class TestUltimateListCtrl(ULC.UltimateListCtrl):
    def __init__(self, parent, log):

        ULC.UltimateListCtrl.__init__(self, parent, -1, agwStyle=ULC.ULC_REPORT|ULC.ULC_SINGLE_SEL|ULC.ULC_VRULES|ULC.ULC_HRULES)

    self.table_fields=['First','Second','Third']
    field_index=0
        for field in self.table_fields:
        info = ULC.UltimateListItem()
        info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT | ULC.ULC_MASK_CHECK
        info._image = []
        info._format = wx.LIST_FORMAT_CENTER
        info._kind = 1      
        info._text = field
        info._font= wx.Font(13, wx.ROMAN, wx.NORMAL, wx.BOLD)
        self.InsertColumnInfo(field_index, info)
        self.SetColumnWidth(field_index,175)
        field_index += 1

    for record_index in range(0,1000):
        for field in self.table_fields:
        if self.table_fields.index(field)==0:
            self.InsertStringItem(record_index, 'Item %d, Column %d' % (record_index,self.table_fields.index(field)),it_kind=1)
        else:
            self.SetStringItem(record_index, self.table_fields.index(field), 'Item %d, Column %d' % (record_index,self.table_fields.index(field)))

class TestFrame(wx.Frame):
    def __init__(self, parent, log):
        wx.Frame.__init__(self, parent, -1, "UltimateListCtrl in wx.LC_VIRTUAL mode", size=(700, 600))
        panel = wx.Panel(self, -1)
        sizer = wx.BoxSizer(wx.VERTICAL)
        listCtrl = TestUltimateListCtrl(panel, log)
        sizer.Add(listCtrl, 1, wx.EXPAND)
        panel.SetSizer(sizer)
        sizer.Layout()
        self.CenterOnScreen()
        self.Show()

if __name__ == '__main__':
    import sys
    app = wx.PySimpleApp()
    frame = TestFrame(None, sys.stdout)
    frame.Show(True)
    app.MainLoop()

【问题讨论】:

  • wxPython 演示中的 UltimateListCtrl 演示使用 wx.LC_VIRTUAL 样式创建数十万条目的虚拟列表。我不确定你在做什么不同,但你应该检查一下。

标签: macos windows-xp wxpython


【解决方案1】:

这个问题已经存在了一段时间,我一直试图在网络上找到解决这个问题的方法(无济于事)。我现在已经解决了我的问题,我在这里发布,以防有​​人发现该解决方案有用,或者可能有更合适的解决方案。


简短回答:您需要手动跟踪已选中和未选中的项目。要检测哪些正在被检查(单击),您可以绑定到 EVT_LIST_ITEM_CHECKING 事件。

长答案:首先,您需要一种方法来跟踪哪些项目已检查或未检查。然后使用它来确定返回 OnGetItemColumnCheck 的内容。例如,您可以像这样使用 item+columns 的列表:

def __init__(...):
    ...
    self.checked = []
    ...

def OnGetItemColumnCheck(self, item, column):
    item_column = (item, column)
    if item_column in self.checked:
        return True
    else:
        return False

您现在需要一种方法来填充该列表。为此,您需要绑定到 EVT_LIST_ITEM_CHECKING 并执行相应的操作:

def __init__(...):
    ...
    self.checked = []
    self.Bind(ULC.EVT_LIST_ITEM_CHECKING, self.OnCheck)
    ...

def OnCheck(self, event):
    item_column = (event.m_itemIndex, event.m_item.GetColumn())
    try:
        idx = self.checked.index(item_column)
    except ValueError:
        idx = None

    if idx == None:
        self.checked.append(item_column)
    else:
        del(self.checked[idx])
    self.Refresh()

self.Refresh() 调用是必不可少的,因为有时复选框不会被重绘。在此之后,您现在应该能够检查和取消选中项目(并且该信息很容易启动!)。这是您经过上述修改的完整代码:

import wx
import random
import os, sys
from wx.lib.agw import ultimatelistctrl as ULC

class TestUltimateListCtrl(ULC.UltimateListCtrl):
    def __init__(self, parent, log):
        ULC.UltimateListCtrl.__init__(self, parent, -1, agwStyle=ULC.ULC_VIRTUAL|ULC.ULC_REPORT|ULC.ULC_SINGLE_SEL|ULC.ULC_VRULES|ULC.ULC_HRULES)
        self.SetItemCount(1000)
        self.table_fields=['First','Second','Third']
        field_index=0
        for field in self.table_fields:
            info = ULC.UltimateListItem()
            info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT | ULC.ULC_MASK_CHECK
            info._image = []
            info._format = wx.LIST_FORMAT_CENTER
            info._kind = 1
            info._text = field
            info._font= wx.Font(13, wx.ROMAN, wx.NORMAL, wx.BOLD)
            self.InsertColumnInfo(field_index, info)
            self.SetColumnWidth(field_index,175)
            field_index += 1

        self.checked = []
        self.Bind(ULC.EVT_LIST_ITEM_CHECKING, self.OnCheck)

    def OnCheck(self, event):
        item_column = (event.m_itemIndex, event.m_item.GetColumn())
        try:
            idx = self.checked.index(item_column)
        except ValueError:
            idx = None

        if idx == None:
            self.checked.append(item_column)
        else:
            del(self.checked[idx])
        self.Refresh()

    def getColumnText(self, index, col):
        item = self.GetItem(index, col)
        return item.GetText()

    def OnGetItemText(self, item, col):
        return "Item %d, Column %d" % (item,col)

    def OnGetItemColumnImage(self, item, col):
        return []

    def OnGetItemImage(self, item):
        return []

    def OnGetItemAttr(self, item):
        return None

    def OnGetItemTextColour(self, item, col):
        return None

    def OnGetItemToolTip(self, item, col):
        return None

    def OnGetItemKind(self, item):
        return 1

    def OnGetItemColumnKind(self, item, col):
        if col==0:
            return self.OnGetItemKind(item)
        return 0

    def OnGetItemColumnCheck(self, item, column):
        item_column = (item, column)
        if item_column in self.checked:
            return True
        else:
            return False

class TestFrame(wx.Frame):
    def __init__(self, parent, log):
        wx.Frame.__init__(self, parent, -1, "UltimateListCtrl in wx.LC_VIRTUAL mode", size=(700, 600))
        panel = wx.Panel(self, -1)
        sizer = wx.BoxSizer(wx.VERTICAL)
        listCtrl = TestUltimateListCtrl(panel, log)
        sizer.Add(listCtrl, 1, wx.EXPAND)
        panel.SetSizer(sizer)
        sizer.Layout()
        self.CenterOnScreen()
        self.Show()

if __name__ == '__main__':
    import sys
    app = wx.PySimpleApp()
    frame = TestFrame(None, sys.stdout)
    frame.Show(True)
    app.MainLoop()

【讨论】:

    猜你喜欢
    • 2014-08-20
    • 1970-01-01
    • 2021-02-11
    • 1970-01-01
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    相关资源
    最近更新 更多