回應列表控制器準確更改

2024-10-17 06:26:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用wxPython处理一个表单,我希望listcrl的值列表根据另一个listcrl的选择进行更改。为此,我使用链接到控制对象的EVT_LIST_ITEM_SELECTEDEVT_LIST_ITEM_DESELECTED事件的方法来调用Publisher.sendMessage。要更改的控件的方法是该发布服务器的订阅服务器。这是可行的:当单击第一个listcrl时,第二个listcrl被刷新。在

问题是数据必须从数据库中刷新,每次选择和取消选择都会发送一条消息。这意味着,即使我只是单击一个项目,数据库也会被查询两次(一次是取消选择,然后是再次进行选择)。如果我按住shift键并单击多选5个项目,则会拨打5个电话。有没有办法让listctrl响应集合,而不是单个选择?在


Tags: 项目对象方法服务器数据库表单列表链接
3条回答

最好的解决方案似乎是使用带有标志的wx.CallAfter来执行一次后续过程:

import wx

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)
        self.list_ctrl_1 = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
        sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_1.Add(self.list_ctrl_1, 1, wx.EXPAND, 0)
        self.list_ctrl_1.InsertColumn(0,"1")
        self.list_ctrl_1.InsertStringItem(0,"HELLO1")
        self.list_ctrl_1.InsertStringItem(0,"HELLO2")
        self.list_ctrl_1.InsertStringItem(0,"HELLO3")
        self.list_ctrl_1.InsertStringItem(0,"HELLO4")
        self.list_ctrl_1.InsertStringItem(0,"HELLO5")
        self.list_ctrl_1.InsertStringItem(0,"HELLO6")
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list_ctrl_1)
        self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected, self.list_ctrl_1)
        self.dirty = False
    def Cleanup(self, StringToPrint):
        print 'No Longer Dirty!'
        self.dirty = False

    def OnItemSelected(self,event):
        print str(self.__class__) + " - OnItemSelected"
        if not self.dirty:
            self.dirty = True
            wx.CallAfter(self.Cleanup)
        event.Skip()

    def OnItemDeselected(self,event):
        print str(self.__class__) + " - OnItemDeselected"
        if not self.dirty:
            self.dirty = True
            wx.CallAfter(self.Cleanup)
        event.Skip()

if __name__ == "__main__":
    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    frame_1 = MyFrame(None, -1, "")
    app.SetTopWindow(frame_1)
    frame_1.Show()
    app.MainLoop()

可以推入自定义事件处理程序

import wx

class MyEventHandler(wx.PyEvtHandler):
        def __init__(self,target):
            self.target = target
            wx.PyEvtHandler.__init__(self)

        def ProcessEvent(self,event):
            # there must be a better way of getting the event type,
            # but I couldn't find it
            if event.GetEventType() == wx.EVT_LEFT_DOWN.evtType[0]:
                print "Got Mouse Down event"
                (item,where) = self.target.HitTest(event.GetPosition())
                if item != -1:
                    print self.target.GetItem(item,0).GetText()
                    print where
                else:
                    print "Not on list item though"
                return True
            else:
                return False

class MyFrame(wx.Frame):
        def __init__(self, *args, **kwds):
           wx.Frame.__init__(self, *args, **kwds)
           self.list_ctrl_1 = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
           self.myevthandler = MyEventHandler(self.list_ctrl_1)
           sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
           sizer_1.Add(self.list_ctrl_1, 1, wx.EXPAND, 0)
           self.list_ctrl_1.InsertColumn(0,"1")
           self.list_ctrl_1.InsertStringItem(0,"HELLO1")
           self.list_ctrl_1.PushEventHandler(self.myevthandler)


if __name__ == "__main__":
    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    frame_1 = MyFrame(None, -1, "")
    app.SetTopWindow(frame_1)
    frame_1.Show()
    app.MainLoop()

你可以试试右键单击EVT_LIST_ITEM_。那应该行得通。否则,您需要在每次触发selection事件时使用一个标志并检查said标志,以确定它是否需要查询数据库。还有一个ultimatelistcrl,一个纯python小部件,您也可以通过黑客攻击来实现这一点。在

相关问题 更多 >