2011-08-14 11 views
5

आप में से किसी को भी कैसे बनाने के लिए एक उदाहरण है संभव निम्नलिखित:wxPython - dynamially एक textctrl में इनपुट के आधार पर एक listctrl अद्यतन

मैं एक listctrl कि प्रदर्शित करता है> 600 आइटम नहीं हैं। अब मुझे इन पाठों को उपयोगकर्ता द्वारा इनपुट किए गए पाठ के लिए खोजना होगा और सूची को अपडेट करना होगा ताकि केवल इस स्ट्रिंग वाले आइटम दिखाए जा सकें।

तो आइए हम कहें कि सूची में "हैलो", "हाय" और "मॉर्निंग" शामिल है। सूची सभी तीन वस्तुओं को प्रदर्शित करता है। अब उपयोगकर्ता textctrl में "h" टाइप करता है, और listctrl को "हैलो" और "हाय" तक सीमित कर दिया जाता है। यदि उपयोगकर्ता इसके बजाय "ओ" टाइप करता है, और सूची "हैलो" और "मॉर्निंग" बन जाती है।

क्या यह संभव है? या किसी सूची में किसी आइटम को ढूंढने का कोई अन्य सुविधाजनक तरीका है? , और मेरे मामले में यह वास्तव में मामला नहीं होगा ...

धन्यवाद Woodpicker

उत्तर

4

- "आपके द्वारा लिखे जाने लगता है" में निर्माण केवल वास्तविक उपयोग की है अगर आप वास्तव में क्या आप के लिए खोज में पता है wxPython डेमो में एक बहुत अच्छा "टाइप-आगे" फ़िल्टर बनाया गया है। source code to Main.py पर देखकर वे इसे "मैन्युअल तरीका", लूप और सूची का पुनर्निर्माण करते हैं। वे एक treeview उपयोग कर रहे हैं, लेकिन विचारों ध्वनि कर रहे हैं:

def OnSearch(self, event=None): 

    value = self.filter.GetValue() 
    if not value: 
     self.RecreateTree() 
     return 

    wx.BeginBusyCursor() 

    for category, items in _treeList: 
     self.searchItems[category] = [] 
     for childItem in items: 
      if SearchDemo(childItem, value): 
       self.searchItems[category].append(childItem) 

    wx.EndBusyCursor() 
    self.RecreateTree()  
+0

शुरू करने 'Main.py' लिए हाइपरलिंक टूटी हुई है। यहां एक कामकाजी लिंक है (2017-12-07) http://svn.wxwidgets.org/svn/wx/wxPython/trunk/demo/Main.py?view=markup और चूंकि wxPython github में स्थानांतरित हो गया है, यहां नवीनतम लिंक है यदि svn repo को हटा दिया गया है: https://github.com/wxWidgets/wxPython/blob/master/demo/Main.py – IceArdor

3

मैं ObjectListView सीधे wx.ListCtrl की तुलना में बेहतर आवरण की तरह। इसमें विजेट की सुविधा के रूप में नियंत्रण में आइटम फ़िल्टर करने की क्षमता शामिल है। आप इसके बारे में यहां पढ़ सकते हैं: http://objectlistview.sourceforge.net/python/features.html#filtering और यहां नियंत्रण के लिए मुख्य पृष्ठ है: http://objectlistview.sourceforge.net/python/

+0

जानना अच्छी बात है। अफसोस की बात यह है कि मैं इस विशिष्ट परियोजना में केवल योगदान देता हूं और इस प्रकार मौजूदा सूची के साथ काम करने के लिए मजबूर हूं ... – Woodpicker

+1

ठीक है, चूंकि ऑब्जेक्टलिस्ट व्यू मूल रूप से ListCtrl के लिए एक रैपर है, तो आप स्रोत कोड पर एक नज़र डाल सकते हैं। तो शायद आप उसकी विधि दोहराना कर सकते हैं। –

1

यहां एक UltimateListCtrl फ़िल्टर करने का एक उदाहरण है। मुझे पता है कि यह 2 साल बाद है, लेकिन मुझे वास्तव में उपयोगी रूप से स्टैक ओवरफ्लो पर अन्य उदाहरण मिल गए हैं। मैं अजगर/wxpython के लिए नया हूँ लेकिन उम्मीद है कि यह उपयोगी होगा। से http://www.blog.pythonlibrary.org/2011/11/02/wxpython-an-intro-to-the-ultimatelistctrl/

import wx 
from wx.lib.agw import ultimatelistctrl as ULC 


class ULC_Panel(wx.Panel): 
    """""" 
    def __init__(self, parent, col_headers=None, list_data=None, options=None, dlg=None, 
      selected_list=None): 
     """Constructor""" 
     wx.Panel.__init__(self, parent) 
     self.options = options 
     self.show_only_selected = False 
     self.filter_string = "" 

     hsizer = wx.BoxSizer(wx.HORIZONTAL) 
     okayButton = wx.Button(self, wx.ID_OK, "OK") 
     okayButton.SetToolTip(wx.ToolTip("Click to close this dialog and use the selections")) 
     self.Bind(wx.EVT_BUTTON, self.OnOkayCanButton, okayButton) 
     hsizer.Add(okayButton, 0, wx.ALL, 5) 
     canButton = wx.Button(self, wx.ID_CANCEL, "Cancel") 
     canButton.SetToolTip(wx.ToolTip("Click to close this dialog and cancel selections")) 
     self.Bind(wx.EVT_BUTTON, self.OnOkayCanButton, canButton) 
     hsizer.Add(canButton, 0, wx.ALL, 5) 
     cb_show_only = wx.CheckBox(self, -1, "Show only selected items?") 
     cb_show_only.SetValue(self.show_only_selected) 
     cb_show_only.SetToolTip(wx.ToolTip("Click to show only selected rows")) 
     self.Bind(wx.EVT_CHECKBOX, self.EvtShowOnly, cb_show_only) 
     hsizer.Add(cb_show_only, 0, wx.ALL, 5) 

     self.stext = wx.StaticText(self, -1, "Filter: ", style=wx.ALIGN_LEFT) 
     self.filtr = wx.TextCtrl(self, -1, "", style=wx.ALIGN_LEFT) 
     self.Bind(wx.EVT_TEXT, self.OnFiltr, self.filtr) 
     fsizer = wx.BoxSizer(wx.HORIZONTAL) 
     fsizer.Add(self.stext, 0, wx.ALL) 
     fsizer.Add(self.filtr, 1, wx.EXPAND) 

     font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) 
     boldfont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) 
     boldfont.SetWeight(wx.BOLD) 
     boldfont.SetPointSize(12) 

     self.ultimateList = ULC.UltimateListCtrl(self, agwStyle = wx.LC_REPORT 
             | wx.LC_VRULES | ULC.ULC_HAS_VARIABLE_ROW_HEIGHT 
             | wx.LC_HRULES) 


     self.checkbox = [None] * len(list_data) 
     if selected_list != None: 
      self.selected = selected_list 
     else: 
      self.selected = [False] * len(list_data) 
     self.rows_max = len(list_data) 
     self.rows_current = -1 
     self.cols_max = len(col_headers) 
     self.cols_extra = 1 
     if options & ULC.ULC_MASK_CHECK: 
      self.cols_extra += 1 
     for i in xrange(self.cols_max+self.cols_extra): 
      info = ULC.UltimateListItem() 
      info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT 
      info._image = [] 
      info._format = 0 
      info._kind = 1 
      width = 150 
      if i >= self.cols_extra: 
       info._text = col_headers[i-self.cols_extra] 
      elif i == 0: 
       info._text = "Row" 
       width = 35 
      elif i == 1 and options & ULC.ULC_MASK_CHECK: 
       info._text = "Select" 
       width = 50 
      self.ultimateList.InsertColumnInfo(i, info) 
      self.ultimateList.SetColumnWidth(i, width) 

     self.list_data = list_data 
     pos = self.populate_table("") 

     if pos != None: 
      self.sz = self.ultimateList.GetItemRect(pos) 
      self.width = self.sz[2] + self.sz[3] 
      self.height = self.sz[1] 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(hsizer, 0, wx.EXPAND) 
     sizer.Add(fsizer, 0, wx.EXPAND) 
     sizer.Add(self.ultimateList, 1, flag=wx.EXPAND) 

     self.SetSizer(sizer) 
     sizer.Fit(self) 

    def EvtShowOnly(self, event): 
     cb = event.GetEventObject() 
     val = cb.GetValue() 
     self.show_only_selected = val 
     pos = self.populate_table(self.filter_string) 
     print "show_only_selected val= ", val 

    def EvtCheckBox(self, event): 
     cb = event.GetEventObject() 
     id = event.GetId() 
     val = cb.GetValue() 
     self.selected[id] = val 
     print "id, val= ", id, val 

    def OnOkayCanButton(self, event): 
     id = event.GetId() 
     dlg.EndModal(id) 

    def myGetNeedWH(self): 
     return (self.width, self.height) 

    def myGetSelectedState(self): 
     return self.selected 

    def populate_table(self, str_in): 
     busy = wx.BusyCursor() 
     if str_in: 
      str_low = str_in.lower() 
     if self.options & ULC.ULC_MASK_CHECK: 
      # if we have widgets in the row then we have to delete 1 row 
      # at a time (or else it leaves some of the widgets) 
      i = self.rows_current 
      #print "i, self.rows_max= ", i, self.rows_max 
      while i >= 0: 
       #print "i= ", i 
       self.ultimateList.DeleteItem(i) 
       i -= 1 
     else: 
      self.ultimateList.DeleteAllItems() 
     row = -1 
     for i in xrange(len(self.list_data)): 
      tlwr = self.list_data[i][0].lower() 
      if not str_in or tlwr.find(str_low) >= 0: 
       if self.show_only_selected and self.selected[i] == False: 
        continue 
       row += 1 
       for j in xrange(self.cols_max+self.cols_extra): 
        if j == 0: 
         pos = self.ultimateList.InsertStringItem(row, str(row)) 
        elif j == 1 and self.options & ULC.ULC_MASK_CHECK: 
         self.checkbox[i] = wx.CheckBox(self.ultimateList, id= i) 
         self.checkbox[i].SetValue(self.selected[i]) 
         self.checkbox[i].SetToolTip(wx.ToolTip("Click to select this row")) 
         self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, self.checkbox[i]) 
         self.ultimateList.SetItemWindow(pos, col=1, wnd=self.checkbox[i], expand=False) 
        else: 
         self.ultimateList.SetStringItem(row, j, self.list_data[i][j-self.cols_extra]) 
     self.rows_current = row 
     return row 

    def OnFiltr(self, event): 
     str1 = event.GetString() 
     id = event.GetId() 
     #print "got txt_tval str[%s]= %s" % (id, str1) 
     self.filter_string = str1 
     pos = self.populate_table(str1) 
     event.Skip() 
     return 


######################################################################## 
class FilterListDiag(wx.Dialog): 
    def __init__(self, parent, id, title, headers=None, data_table=None, options=None, selected_list=None): 
     wx.Dialog.__init__(self, parent, id, title="", style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) 
     options_in = options 

     self.panel = ULC_Panel(self, col_headers=headers, list_data=data_table, options=options_in, 
       dlg=self, selected_list=selected_list) 
     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.panel, 1, wx.EXPAND) 
     self.SetSizer(sizer) 
     (self.width, self.height) = self.panel.myGetNeedWH() 

    def myGetNeedWH(self): 
     return (self.width, self.height) 

    def myGetSelectedState(self): 
     return self.panel.myGetSelectedState() 

class TestFrame(wx.Frame): 
    def __init__(self): 
     """Constructor""" 
     wx.Frame.__init__(self, None, title="MvP UltimateListCtrl Demo", size=(850,600)) 

#---------------------------------------------------------------------- 
if __name__ == "__main__": 
    app = wx.App(False) 
    frame = TestFrame() 
    col_headers = ['col0', 'col1', 'col2'] 
    list_data = [ 
      ["Newsboys", "Go", "Rock"], 
      ["Puffy", "Bring It!", "Pop"], 
      ["Family Force 5", "III", "Pop"], 
      ["Me2", "III", "Pop"], 
      ["Duffy", "III", "Pop"], 
      ["Fluffy", "III", "Pop"], 
    ] 
    # sel_data passes in a list of which rows are already selected 
    sel_data = [ 
      False, 
      False, 
      False, 
      False, 
      True, 
      False, 
    ] 
    opt=ULC.ULC_MASK_CHECK # just reusing this to indicate I want a column of checkboxes. 
    dlg = FilterListDiag(frame, -1, "hi", headers=col_headers, data_table=list_data, options=opt, selected_list=sel_data) 
    (w, h) = dlg.myGetNeedWH() 
    print w,h 
    dlg.SetSizeWH(w, 300) 
    val = dlg.ShowModal() 
    selected = dlg.myGetSelectedState() 
    print "okay, can, val= ", wx.ID_OK, wx.ID_CANCEL, val 
    dlg.Destroy() 
    print 'selected=', selected 
संबंधित मुद्दे