2010-05-26 3 views
2

Je réécris ce post pour clarifier certaines choses et fournir une définition de classe complète pour la liste virtuelle avec laquelle je rencontre des problèmes. La classe est définie comme ceci:wxPython La colonne ListCtrl ignore les champs spécifiques

 
from wx import ListCtrl, LC_REPORT, LC_VIRTUAL, LC_HRULES, LC_VRULES, \ 
    EVT_LIST_COL_CLICK, EVT_LIST_CACHE_HINT, EVT_LIST_COL_RIGHT_CLICK, \ 
    ImageList, IMAGE_LIST_SMALL, Menu, MenuItem, NewId, ITEM_CHECK, Frame, \ 
    EVT_MENU 

class VirtualList(ListCtrl): 
    def __init__(self, parent, datasource = None, 
       style = LC_REPORT | LC_VIRTUAL | LC_HRULES | LC_VRULES): 
    ListCtrl.__init__(self, parent, style = style) 

    self.columns = [] 
    self.il = ImageList(16, 16) 

    self.Bind(EVT_LIST_CACHE_HINT, self.CheckCache) 
    self.Bind(EVT_LIST_COL_CLICK, self.OnSort) 

    if datasource is not None: 
     self.datasource = datasource 
     self.Bind(EVT_LIST_COL_RIGHT_CLICK, self.ShowAvailableColumns) 

     self.datasource.list = self 

     self.Populate() 

    def SetDatasource(self, datasource): 
    self.datasource = datasource 

    def CheckCache(self, event): 
    self.datasource.UpdateCache(event.GetCacheFrom(), event.GetCacheTo()) 

    def OnGetItemText(self, item, col): 
    return self.datasource.GetItem(item, self.columns[col]) 

    def OnGetItemImage(self, item): 
    return self.datasource.GetImg(item) 

    def OnSort(self, event): 
    self.datasource.SortByColumn(self.columns[event.Column]) 
    self.Refresh() 

    def UpdateCount(self): 
    self.SetItemCount(self.datasource.GetCount()) 

    def Populate(self): 
    self.UpdateCount() 

    self.datasource.MakeImgList(self.il) 

    self.SetImageList(self.il, IMAGE_LIST_SMALL) 

    self.ShowColumns() 

    def ShowColumns(self): 
    for col, (text, visible) in enumerate(self.datasource.GetColumnHeaders()): 
     if visible: 
     self.columns.append(text) 
     self.InsertColumn(col, text, width = -2) 

    def Filter(self, filter): 
    self.datasource.Filter(filter) 

    self.UpdateCount() 

    self.Refresh() 

    def ShowAvailableColumns(self, evt): 
    colMenu = Menu() 

    self.id2item = {} 

    for idx, (text, visible) in enumerate(self.datasource.columns): 
     id = NewId() 

     self.id2item[id] = (idx, visible, text) 

     item = MenuItem(colMenu, id, text, kind = ITEM_CHECK) 
     colMenu.AppendItem(item) 

     EVT_MENU(colMenu, id, self.ColumnToggle) 

     item.Check(visible) 

    Frame(self, -1).PopupMenu(colMenu) 

    colMenu.Destroy() 

    def ColumnToggle(self, evt): 
    toggled = self.id2item[evt.GetId()] 

    if toggled[1]: 
     idx = self.columns.index(toggled[2]) 

     self.datasource.columns[toggled[0]] = (self.datasource.columns[toggled[0]][0], False) 

     self.DeleteColumn(idx) 

     self.columns.pop(idx) 

    else: 
     self.datasource.columns[toggled[0]] = (self.datasource.columns[toggled[0]][0], True) 

     idx = self.datasource.GetColumnHeaders().index((toggled[2], True)) 

     self.columns.insert(idx, toggled[2]) 

     self.InsertColumn(idx, toggled[2], width = -2) 

    self.datasource.SaveColumns() 

J'ai ajouté des fonctions qui permettent la colonne Basculement qui facilitent ma description de la question que je rencontre. Sur la troisième instance de cette classe dans mon application, la colonne à l'index 1 n'affichera pas les valeurs de chaîne. Les valeurs entières sont affichées correctement. Si j'ajoute des instructions d'impression à ma méthode OnGetItemText, les valeurs s'affichent correctement dans ma console. Ce comportement n'est pas présent dans les deux premières instances de cette classe et ma classe ne contient aucun code de vérification de type en ce qui concerne l'affichage de la valeur.

Il a été suggéré par quelqu'un sur le groupe d'utilisateurs wxPython que je crée un exemple autonome qui démontre ce problème si je peux. Je travaille là-dessus, mais je n'ai pas encore eu le temps de créer un échantillon qui ne repose pas sur l'accès à la base de données. Toute suggestion ou conseil serait le plus apprécié. Je m'arrache les cheveux sur celui-ci.

+0

Etes-vous sûr que ListCtrl est à blâmer? Essayez 'print item, col, data' dans' OnGetItemText' pour voir quand il vous appelle et ce que vous retournez. – FogleBird

+0

J'ai remarqué un motif intéressant dans les valeurs non affichées. Dans l'instance de la liste, j'ai des problèmes avec les champs qui n'affichent pas les valeurs de chaîne. Les champs qui s'afficheront contiennent des valeurs numériques. Ce comportement n'est pas présent dans les deux premières instances de ma classe dans mon application et n'apparaît que dans la colonne à l'index 1 dans la troisième instance. Je n'ai aucun type de code lié dans ma classe de liste. Je mettrai à jour ce post avec une définition de classe complète la prochaine fois que je serai devant le code s'il n'y a pas d'autres suggestions. –

+0

Dans le cas où quelqu'un serait intéressé, j'ai généré un exemple autonome montrant ce comportement disponible ici: http://groups.google.com/group/wxpython-users/browse_thread/thread/f45b211af20e1cef/bdff95491b305400?lnk=raot#bdff95491b305400. Merci d'avance. –

Répondre

0

Il y a un problème avec l'objet natif dans Windows. Si GetImg renvoie None au lieu de -1, la liste a un problème avec la colonne 1 pour une raison quelconque. Cela vient de Robin sur le post du groupe Google pour ce numéro.

0

Utilisez-vous le code de démonstration wxPython pour les contrôles de liste virtuelle? Vous devez effectuer quelques tâches de comptabilité, par exemple définir la propriété ItemCount. Un commentaire à propos de votre méthode OnGetItemText: Comme il n'y a pas d'autre instruction return, elle retournera None si les données sont None, donc votre test n'a aucun effet.

Que diriez-vous de return data or "" à la place?

+0

Le test de 'si les données ne sont pas None:' était significatif avant un refactor. Auparavant, les données étaient un objet dictionnaire et j'ai tenté de renvoyer la valeur à partir des données. Si les données étaient None alors j'ai eu une erreur de clé. J'ai changé les méthodes, donc je ne transmets pas autant de données et cela rend la vérification superflue. Je vous remercie de l'avoir signalé. Ma classe complète définit correctement ItemCount. J'ai omis des parties de la définition de classe pour économiser de l'espace. –

Questions connexes