2010-07-02 9 views
3

J'ai créé un fichier wx.grid.Grid avec une classe dérivée wx.grid.PyGridTableBase pour fournir ses données. Je veux aussi contrôler les éditeurs utilisés sur la table. À cette fin, je défini la méthode suivanteErreur de segmentation wxPython avec les éditeurs

def GetAttr(self, row, col, kind): 
    attr = wx.grid.GridCellAttr() 
    if col == 0: 
     attr.SetEditor(wx.grid.GridCellChoiceEditor()) 
    return attr 

Cependant, cela provoque une erreur de segmentation à chaque fois que je tente de créer l'éditeur dans la grille. Je l'ai fait essayer de créer l'éditeur au préalable et en passant en tant que paramètre, mais reçu l'erreur:

TypeError: in method 'GridCellAttr_SetEditor', expected argument 2 of type 
'wxGridCellEditor *' 

Je soupçonne que la deuxième erreur est provoquée par la prise de possession GridCellAttr hors puis détruire mon rédacteur en chef.

J'ai également essayé d'utiliser la méthode SetDefaultEditor sur wx.grid.Grid et cela fonctionne, mais ne me permet naturellement pas d'avoir une stratégie d'édition spécifique à une colonne.

Voir Exemple complet du programme plantage: http://pastebin.com/SEbhvaKf

Répondre

4

Je compris le problème:

Le code wxWidgets suppose que le même éditeur sera toujours retourné de GetCellAttr. Renvoyer un éditeur différent chaque fois que je le faisais causait des erreurs de segmentation.

Afin de retourner le même éditeur plusieurs fois, j'ai également besoin d'appeler IncRef() sur l'éditeur pour le garder en vie.

Pour quelqu'un d'autre frapper le même problème à l'avenir, voir mon code de travail:

import wx.grid 

app = wx.PySimpleApp() 

class Source(wx.grid.PyGridTableBase): 
    def __init__(self): 
     super(Source, self).__init__() 
     self._editor = wx.grid.GridCellChoiceEditor() 

    def IsEmptyCell(self, row, col): 
     return False 

    def GetValue(self, row, col): 
     return repr((row, col)) 

    def SetValue(self, row, col, value): 
     pass 

    def GetNumberRows(self): 
     return 5 

    def GetNumberCols(self): 
     return 5 

    def GetAttr(self, row, col, kind): 
     attr = wx.grid.GridCellAttr() 
     self._editor.IncRef() 
     attr.SetEditor(self._editor) 
     return attr 


frame = wx.Frame(None) 
grid = wx.grid.Grid(frame) 
grid.SetTable(Source()) 
frame.Show() 

app.MainLoop() 
0

Cela devrait résoudre:

import wx 
import wx.grid as gridlib 

et changer:

def GetAttr(self, row, col, kind): 
    attr = gridlib.GridCellAttr() 
    if col == 0: 
     attr.SetEditor(gridlib.GridCellChoiceEditor()) 
    return attr 

obs: Je ne sais pas pourquoi vous avez besoin de le faire de cette façon parce que:

>>> import wx 
>>> attr = wx.grid.GridCellAttr() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'module' object has no attribute 'grid' 

Ne pas travailler, mais:

import wx.grid as gridlib 
attr = gridlib.GridCellAttr() 

œuvres ... mais:

print attr 
<wx.grid.GridCellAttr; proxy of <wx.grid.GridCellAttr; proxy of <Swig Object of type 'wxGridCellAttr *' at 0x97cb398> > > 

Il dit: <wx.grid.GridCellAttr; proxy of <wx.grid.GridCellAttr>...>!

OBS2: si vous utilisez la ChoiceEditor sur toute la colonne 0, vous pouvez également définir une seule fois avant de montrer la grille avec:

attr.SetEditor(gridlib.GridCellChoiceEditor()) 
yourGrid.SetColAttr(0, attr) 

et vous pouvez supprimer tout le code de la méthode GetAttr (Je pense que ça devrait être plus rapide - mais je n'ai jamais chronométré ça).

+0

si vous importez wx.grid au lieu de simplement WX, alors vous ne serez pas l'erreur d'attribut. Autre que de changer le style d'importation, je ne vois pas ce que vous faites différemment qui est censé le réparer. L'utilisation de SetColAttr fonctionne très bien, et c'est une meilleure façon de le faire, merci. Mais je voudrais savoir pourquoi je recevais des fautes de segmentation ... –

+0

Oui, exactement, le correctif est de changer le style d'importation. Comme vous pouvez le voir dans les sorties de la console, les objets de wx.grid ne fonctionnent pas si vous importez 'wx' au lieu de' wx.grid'. Je ne sais pas pourquoi, car importé, l'objet est listé comme 'wx.grid'. De toute façon, c'est toujours comme ça, pas seulement dans votre cas. Vous avez eu la faute de segmentation uniquement lors de l'utilisation de l'éditeur car il avait un type incorrect ou aucun type car il n'était pas correctement initialisé avec wx.grid. – laurent

+0

La modification du style d'importation ne résout pas le problème. (Oui, je l'ai essayé pour être sûr) –

Questions connexes