IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

wxPython Discussion :

Saisie semi automatique


Sujet :

wxPython

  1. #1
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4
    Par défaut Saisie semi automatique
    Bonjour,

    Voila quelques semaines que j'ai commencé a utiliser python pour developper une application client pour une base de données.

    Afin de faciliter certaines recherches, je voudrais y mettre des champs avec saisie semi automatique (comme dans certains navigateurs).

    J'ai essayé de faire ce champ avec une comboBox:
    Ca marche presque... quand on tappe un texte puis une touche directionnelle , il trouve tout seul l'element correspondant a la chaine tappée.
    Je me suis donc dit qu'il faudrait utiliser la methode attachée (Bind) a l' evenement 'touche directionnelle appuyée' pour l'attacher a l'evenement 'texte rentré' (EVT_TEXT). Mais je me suis un peu heurté a un mur en ouvrant la classe du package.

    Autre piste : la classe BaseMaskedComboBox
    'Base class for generic masked edit comboboxes; allows auto-complete of values.' Mais j'arrive pas non plus a l'utiliser.

    Donc si certains aguérris sont deja passés par la , j'aimerais bien qu'ils m'orientent dans cette jungle du wxPython.

    Merci

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    259
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 259
    Par défaut
    Salut!
    Bon, je sais pas si ça va répondre à ta question, parce que je viens de tomber dessus, et je ne sais pas du tout comment ça marche ni ce que ça fait (je sens que ma réponse va être utile, je sais pas pourquoi... )
    J'ai trouvé une EditableListBox dans le module wx.gizmos, tu peux trouver la référence ici
    Mais comme je te l'ai dit, je ne sais pas du tout ce que ça fait, donc il se peut que ça ne réponde pas du tout à ta demande, désolé.

    P.S.: petite précision, je ne sais pas si tu es allé voir la doc wxpython, mais apparemment, il existe des classes pour personnaliser une combo box. Encore une fois, je n'ai pas testé, donc je ne peux pas te dire si ça correspond à tes attentes ou pas.

  3. #3
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4
    Par défaut ca a pas l'air simple
    J'ai regardé un peu la classe EditableListbox:
    sur la doc officielle j'ai rien compris , ca me dit pas ce que le widget fait
    Alors en cherchant j'ai trouvé un pti pdf avec des screenshots , c'est tout de suite plus clair...:
    Sur la page 15, on voit que l'editable listbox ressemble plutot a une listeBox dans laquelle tu peux rentrer des elements a la main.

    Sinon le module wx.combo a l'air interessant mais j'arrive pas l'utiliser (je trouve pas de code source d'un exemple d'utilisation sur le net)

  4. #4
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4
    Par défaut j'ai trouvé...
    Bon bah j'ai finalement trouvé une solution toute faite (et meme un peu trop bien faite) a cette adresse.

    Maintenant, la solution est un peu trop complete pour moi. Ca va etre dur de separer ce qui m'est vraiment necessaire car le mec qui a ecrit ca est pas un rigolo . Il a rajouté plein d'options.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    259
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 259
    Par défaut
    Ouaip, effectivement
    Si t'arrives à t'en sortir, je veux bien la solution, parce que là, moi, je sèche : y a plus rien qui s'affiche!

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    259
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 259
    Par défaut
    Bon, après de nombreux efforts et beaucoup de difficultés, voilà ce que j'ai réussi à cracher :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    import locale, wx, sys, cStringIO
     
    import  wx.lib.mixins.listctrl  as  listmix
     
    from wx import ImageFromStream, BitmapFromImage
    #----------------------------------------------------------------------
    def getSmallUpArrowData():
        return \
    '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
    \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
    \x00\x00<IDAT8\x8dcddbf\xa0\x040Q\xa4{h\x18\xf0\xff\xdf\xdf\xffd\x1b\x00\xd3\
    \x8c\xcf\x10\x9c\x06\xa0k\xc2e\x08m\xc2\x00\x97m\xd8\xc41\x0c \x14h\xe8\xf2\
    \x8c\xa3)q\x10\x18\x00\x00R\xd8#\xec\xb2\xcd\xc1Y\x00\x00\x00\x00IEND\xaeB`\
    \x82'
     
    def getSmallUpArrowBitmap():
        return BitmapFromImage(getSmallUpArrowImage())
     
    def getSmallUpArrowImage():
        stream = cStringIO.StringIO(getSmallUpArrowData())
        return ImageFromStream(stream)
     
     
    def getSmallDnArrowData():
        return \
    "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
    \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
    \x00\x00HIDAT8\x8dcddbf\xa0\x040Q\xa4{\xd4\x00\x06\x06\x06\x06\x06\x16t\x81\
    \xff\xff\xfe\xfe'\xa4\x89\x91\x89\x99\x11\xa7\x0b\x90%\ti\xc6j\x00>C\xb0\x89\
    \xd3.\x10\xd1m\xc3\xe5*\xbc.\x80i\xc2\x17.\x8c\xa3y\x81\x01\x00\xa1\x0e\x04e\
    ?\x84B\xef\x00\x00\x00\x00IEND\xaeB`\x82"
     
    def getSmallDnArrowBitmap():
        return BitmapFromImage(getSmallDnArrowImage())
     
    def getSmallDnArrowImage():
        stream = cStringIO.StringIO(getSmallDnArrowData())
        return ImageFromStream(stream)
    #----------------------------------------------------------------------
     
    class myListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
        def __init__(self, parent, ID=-1, pos=wx.DefaultPosition,
                     size=wx.DefaultSize, style=0):
            wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
            listmix.ListCtrlAutoWidthMixin.__init__(self)
     
    class TextCtrlAutoComplete (wx.TextCtrl, listmix.ColumnSorterMixin ):
     
        def __init__ ( self, parent, choices = None) :
            '''
            Constructor works just like wx.TextCtrl except you can pass in a
            list of choices.  You can also change the choice list at any time
            by calling setChoices.
            '''
     
            wx.TextCtrl.__init__(self, parent,style=wx.TE_PROCESS_ENTER)
     
            #Some variables
            self._dropDownClick = True
            self._choices = choices
            self._lastinsertionpoint = 0
            self._matchFunction = None
     
            #widgets
            self.dropdown = wx.PopupWindow( self )
     
            #Create the list and bind the events
            self.dropdownlistbox = myListCtrl( self.dropdown, style=wx.LC_REPORT|wx.LC_SINGLE_SEL,pos=wx.Point( 0, 0) )
     
            #initialize the parent
            listmix.ColumnSorterMixin.__init__(self, 1)
     
            #load the data
            self.SetChoices ( choices )
     
            gp = self
            while ( gp != None ) :
                gp.Bind ( wx.EVT_MOVE , self.onControlChanged, gp )
                gp.Bind ( wx.EVT_SIZE , self.onControlChanged, gp )
                gp = gp.GetParent()
     
            self.Bind( wx.EVT_KILL_FOCUS, self.onControlChanged, self )
            self.Bind( wx.EVT_TEXT , self.onEnteredText, self )
            self.Bind( wx.EVT_KEY_DOWN , self.onKeyDown, self )
     
            #If need drop down on left click
            if self._dropDownClick:
                self.Bind ( wx.EVT_LEFT_DOWN , self.onClickToggleDown, self )
                self.Bind ( wx.EVT_LEFT_UP , self.onClickToggleUp, self )
     
            self.dropdown.Bind( wx.EVT_LISTBOX , self.onListItemSelected, self.dropdownlistbox )
            self.dropdownlistbox.Bind(wx.EVT_LEFT_DOWN, self.onListClick)
            self.dropdownlistbox.Bind(wx.EVT_LEFT_DCLICK, self.onListDClick)
     
            self.il = wx.ImageList(16, 16)
     
            self.sm_dn = self.il.Add(getSmallDnArrowBitmap())
            self.sm_up = self.il.Add(getSmallUpArrowBitmap())
     
            self.dropdownlistbox.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
     
     
        #-- methods called from mixin class
        def GetSortImages(self):
            return (self.sm_dn, self.sm_up)
     
        def GetListCtrl(self):
            return self.dropdownlistbox
     
        # -- event methods
        def onListClick(self, evt):
            toSel = self.dropdownlistbox.HitTest( evt.GetPosition() )[0]
            #no values on poition, return
            if toSel == -1: return
            self.dropdownlistbox.Select(toSel)
     
        def onListDClick(self, evt):
            self._setValueFromSelected()
     
        def onEnteredText(self, event):
            text = event.GetString()
     
            if not text:
                # control is empty; hide dropdown if shown:
                if self.dropdown.IsShown():
                    self._showDropDown(False)
                event.Skip()
                return
     
     
            found = False
            choices = self._choices
     
            for numCh, choice in enumerate(choices):
                if choice.lower().startswith(text.lower()) :
                    found = True
                    break
     
            if found:
                self._showDropDown(True)
                item = self.dropdownlistbox.GetItem(numCh)
                toSel = item.GetId()
                self.dropdownlistbox.Select(toSel)
            else:
                self.dropdownlistbox.Select(self.dropdownlistbox.GetFirstSelected(), False)
                self._showDropDown(False)
     
            self._listItemVisible()
     
            event.Skip ()
     
        def onKeyDown ( self, event ) :
            """ Do some work when the user press on the keys:
                up and down: move the cursor
                left and right: move the search
            """
            skip = True
            sel = self.dropdownlistbox.GetFirstSelected()
            visible = self.dropdown.IsShown()
     
            KC = event.GetKeyCode()
            if KC == wx.WXK_DOWN :
                if sel < (self.dropdownlistbox.GetItemCount () - 1) :
                    self.dropdownlistbox.Select ( sel+1 )
                    self._listItemVisible()
                self._showDropDown ()
                skip = False
            elif KC == wx.WXK_UP :
                if sel > 0 :
                    self.dropdownlistbox.Select ( sel - 1 )
                    self._listItemVisible()
                self._showDropDown ()
                skip = False
            elif KC == wx.WXK_LEFT :
                self._showDropDown ()
            elif KC == wx.WXK_RIGHT:
                self._showDropDown()
     
            if visible :
                if event.GetKeyCode() == wx.WXK_RETURN :
                    self._setValueFromSelected()
                    skip = False
                if event.GetKeyCode() == wx.WXK_ESCAPE :
                    self._showDropDown( False )
                    skip = False
            if skip :
                event.Skip()
     
        def onListItemSelected (self, event):
            self._setValueFromSelected()
            event.Skip()
     
        def onClickToggleDown(self, event):
            self._lastinsertionpoint = self.GetInsertionPoint()
            event.Skip ()
     
        def onClickToggleUp ( self, event ) :
            if ( self.GetInsertionPoint() == self._lastinsertionpoint ) :
                self._showDropDown ( not self.dropdown.IsShown() )
            event.Skip ()
     
        def onControlChanged(self, event):
            self._showDropDown( False )
            event.Skip()
     
     
        # -- Interfaces methods
        def SetChoices(self, choices):
            '''
            Sets the choices available in the popup wx.ListBox.
            The items will be sorted case insensitively.
            '''
            self._choices = choices
            flags = wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_NO_HEADER
            self.dropdownlistbox.SetWindowStyleFlag(flags)
     
            self.dropdownlistbox.InsertColumn(0, "")
     
            for num, colVal in enumerate(self._choices):
                index = self.dropdownlistbox.InsertImageStringItem(sys.maxint, colVal, -1)
     
            self._setListSize()
     
        #-- Internal methods
        def _setValueFromSelected( self ) :
             '''
             Sets the wx.TextCtrl value from the selected wx.ListCtrl item.
             Will do nothing if no item is selected in the wx.ListCtrl.
             '''
             sel = self.dropdownlistbox.GetFirstSelected()
             if sel > -1:
                itemtext = self.dropdownlistbox.GetItem(sel, 0).GetText()
                dd = self.dropdownlistbox
                values = [dd.GetItem(sel, x).GetText()
                    for x in xrange(dd.GetColumnCount())]
     
                self.SetValue (itemtext)
                self.SetInsertionPointEnd ()
                self.SetSelection ( -1, -1 )
                self._showDropDown ( False )
     
     
        def _showDropDown ( self, show = True ) :
            '''
            Either display the drop down list (show = True) or hide it (show = False).
            '''
            if show :
                size = self.dropdown.GetSize()
                width,height = self.GetSizeTuple()
                x, y = self.ClientToScreenXY (0,height)
                size.SetWidth(width)
                self.dropdown.SetSize(size)
                self.dropdownlistbox.SetSize(self.dropdown.GetClientSize())
                self.dropdown . SetPosition ( wx.Point(x-2, y-3) )
            self.dropdown.Show ( show )
     
        def _listItemVisible( self ) :
            '''
            Moves the selected item to the top of the list ensuring it is always visible.
            '''
            toSel =  self.dropdownlistbox.GetFirstSelected ()
            if toSel == -1: return
            self.dropdownlistbox.EnsureVisible( toSel )
     
        def _setListSize(self):
            choices = self._choices
     
            longest = 0
            for choice in choices :
                longest = max(len(choice), longest)
     
            longest += 3
            itemcount = min( len( choices ) , 7 ) + 2
            charheight = self.dropdownlistbox.GetCharHeight()
            charwidth = self.dropdownlistbox.GetCharWidth()
            self.popupsize = wx.Size( -1, charheight*itemcount )
            self.dropdownlistbox.SetSize ( self.popupsize )
            self.dropdown.SetClientSize( self.popupsize )
     
     
     
     
    class test:
        def __init__(self):
            args = dict()
            args["choices"] = [
                            'aardvark', 'abandon', 'acorn', 'acute', 'adore',
                            'aegis', 'ascertain', 'asteroid',
                            'beautiful', 'bold', 'classic',
                            'daring', 'dazzling', 'debonair', 'definitive',
                            'effective', 'elegant',
                            'http://python.org', 'http://www.google.com',
                            'fabulous', 'fantastic', 'friendly', 'forgiving', 'feature',
                            'sage', 'scarlet', 'scenic', 'seaside', 'showpiece', 'spiffy', 'srierser',
                            'www.wxPython.org', 'www.osafoundation.org'
                            ]
     
     
            app = wx.PySimpleApp(redirect=True, filename="err.log")
            frm = wx.Frame(None,-1,"Test",style=wx.TAB_TRAVERSAL|wx.DEFAULT_FRAME_STYLE)
            panel = wx.Panel(frm)
            sizer = wx.BoxSizer(wx.VERTICAL)
     
            self._ctrl = TextCtrlAutoComplete(panel, **args)
            but = wx.Button(panel,label="Set other multi-choice")
     
            sizer.Add(self._ctrl, 0, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
            panel.SetAutoLayout(True)
            panel.SetSizer(sizer)
            sizer.Fit(panel)
            sizer.SetSizeHints(panel)
            panel.Layout()
            app.SetTopWindow(frm)
            frm.Show()
            but.SetFocus()
            app.MainLoop()
     
    if __name__ == "__main__":
        test()
    Problèmes : je n'ai pas la flèche à droite pour faire comme si c'était une vraie combobox; à mon avis, y a plein d'autres trucs qui peuvent être modifiés (je suis par exemple certain qu'il y a au moins deux colonnes dans ma liste, mais je ne sais pas comment faire pour qu'il n'y en ait plus qu'une avec des données dedans - parce que une seule colonne vide, j'y suis arrivé! )
    Donc si quelqu'un passe par là avec des idées...
    Ciao

  7. #7
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4
    Par défaut c'est deja pas mal
    Merci, c'est deja bien utile ce que tu a fais.
    Sinon j'ai trouvé un truc un peu basique à cette adresse ( y a pas la popup window) mais c'est sous forme de combobox.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    259
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 259
    Par défaut
    Oh punaise!!
    Je viens de me rendre compte à l'instant que la barre d'adresse dans IE7 n'est pas non plus une "vraie" combobox!!
    Du coup, ça me donne une idée que je n'ai pas assez creusée apparemment : si à la place du TextCtrl, on met une Combobox, il devrait y avoir moyen de jouer avec la popup et le dropdown... enfin, je crois
    Je m'y attèle de suite et je te tiens au courant.

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    259
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 259
    Par défaut
    Non, ben non, je me suis enflammé. Pendant un temps, je me suis cru intelligent, mais non
    Pas moyen de faire quoi que ce soit en remplaçant par une combobox...
    Désolé pour la fausse joie. Je crois qu'il ne me reste plus qu'à trouver de jolies images de boutons et aussi de trouver pourquoi j'ai deux colonnes dans la liste!!!!!

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    259
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 259
    Par défaut
    Salut!
    Bon, je sais pas si ce sujet est toujours d'actualité, en tout cas, pour moi, il l'était encore hier.
    Donc, après moults efforts insensés, j'ai enfin réussi, je crois, à épurer au maximum cette combobox pour qu'elle fasse ce qu'on voulait qu'elle fasse. Et je dois dire que je suis pas peu fier de moi!
    Contrairement au lien que tu as envoyé, elle n'est pas du tout personnalisable, donc j'espère que ça t'ira.
    Voilà l'engin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    class myListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
        def __init__(self, parent):
            wx.ListCtrl.__init__(self, parent,-1,pos=wx.Point(0,0),style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_NO_HEADER)
            listmix.ListCtrlAutoWidthMixin.__init__(self) # nécessaire pour redimensionner automatiquement la colonne de la liste
    	#end __init__
    #end myListCtrl
     
    class Combo(wx.Panel):
    	def __init__(self,parent,width,choix=None):
    		wx.Panel.__init__(self,parent,-1,style=wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
    		self.choix = choix
    		sizer = wx.GridBagSizer(0,0)
     
    # Composants du combobox
    		self.texte = wx.TextCtrl(self,size=(width,-1),style=wx.TE_PROCESS_ENTER)
    		self.dropdown = wx.PopupWindow(self.texte)
    		self.dropdown.Show(False)
    		self.dropdownlistbox = myListCtrl(self.dropdown)
    		image_button = wx.Bitmap("Image/fleche_bas.gif")
    		self.button = SButton(self,(13,21),image_button,(7,10)) # SButton est une classe que j'ai pu créer en imitant le dossier ShapedButton de l'adresse http://xoomer.alice.it/infinity77/main/freeware.html#shapedbutton, mais un bouton ordinaire fait l'affaire, forcément.
    # Fin Composants
     
    		sizer.Add(self.texte,(0,0),(1,1))
    		sizer.Add(self.button,(0,1),(1,1))
    		self.SetSizer(sizer)
     
    		self.SetChoices()
     
    # Evènements sur les composants		
    		self.button.Bind(wx.EVT_LEFT_UP,self.OnClickUp)
    		self.button.Bind(wx.EVT_KILL_FOCUS,self.OnControlChanged)
     
    		self.texte.Bind(wx.EVT_KILL_FOCUS,self.OnControlChanged)
    		self.texte.Bind(wx.EVT_TEXT,self.OnEnteredText)
    		self.texte.Bind( wx.EVT_KEY_DOWN,self.OnKeyDown)
     
    		self.dropdownlistbox.Bind(wx.EVT_LEFT_DCLICK,self.OnListDClick)
     
    		gp = self
    		while(gp != None) :
    			gp.Bind(wx.EVT_MOVE,self.OnControlChanged)
    			gp.Bind(wx.EVT_SIZE,self.OnControlChanged)
    			gp = gp.GetParent()
    		#end while
    # Fin Evènements
    	#end __init__
     
    	def ListItemVisible(self) :
    		"Assure que l'item sélectionné est toujours visible"
    		toSel =  self.dropdownlistbox.GetFirstSelected()
    		if toSel == -1: return
    		self.dropdownlistbox.EnsureVisible(toSel)
    	#end ListItemVisible
     
    	def OnClickUp(self,evt) :
    		"Montre la liste ou la cache suivant le cas"
    		self.ShowDropDown(not self.dropdown.IsShown())
    		evt.Skip ()
    	#end OnClickUp
     
    	def OnControlChanged(self,evt):
    		"Cache la liste quand le contrôle perd le focus (quand on bouge la fenêtre, quand on redimensionne ou quand on clique à côté"
    		if isinstance(evt,wx.MoveEvent) | isinstance(evt,wx.SizeEvent) : # on bouge la fenêtre, on redimensionne
    			self.ShowDropDown(False)
    		#end if
     
    		if (self.FindFocus() <> self.button) & (self.FindFocus() <> self.texte) : # le contrôle perd le focus
    			self.ShowDropDown(False)
    		#end if
    		evt.Skip()
    	#end OnControlChanged
     
    	def OnEnteredText(self,evt):
    		"Vérifie si un mot de la liste correspond à ce qu'il y a d'écrit"
    		text = evt.GetString() # on récupère ce qu'il y a dans le TextCtrl
     
    		if not text: # le TextCtrl est vide, on cache le dropdown si visible
    			if self.dropdown.IsShown():
    				self.ShowDropDown(False)
    			#end if
    			evt.Skip()
    			return
    		#end if
     
    		found = False
     
    		for numCh,choice in enumerate(self.choix):
    			if choice.lower().startswith(text.lower()) : # on compare la liste avec le texte
    				found = True
    				break # dès que ça correspond, on quitte
    			#end if
    		#end for
     
    		if found: # on a trouvé une correspondance => on montre la liste avec l'élèment sélectionné
    			self.ShowDropDown(True)
    			item = self.dropdownlistbox.GetItem(numCh)
    			toSel = item.GetId()
    			self.dropdownlistbox.Select(toSel)
    		else:
    			self.dropdownlistbox.Select(self.dropdownlistbox.GetFirstSelected(),False)
    			self.ShowDropDown(False)
    		#end if
     
    		self.ListItemVisible()
     
    		evt.Skip ()
    	#end OnEnteredText
     
    	def OnKeyDown(self,event) :
    		skip = True
    		sel = self.dropdownlistbox.GetFirstSelected()
     
    		KC = event.GetKeyCode()
    		if KC == wx.WXK_DOWN : # on appuye sur la flèche du bas => on sélectionne l'item du dessous
    			if sel < (self.dropdownlistbox.GetItemCount() - 1) :
    				self.dropdownlistbox.Select(sel+1)
    				self.ListItemVisible()
    			#end if
    			self.ShowDropDown()
    			skip = False
    		elif KC == wx.WXK_UP : # on appuye sur la flèche du haut => on sélectionne l'item du dessus
    			if sel > 0 :
    				self.dropdownlistbox.Select(sel-1)
    				self.ListItemVisible()
    			#end if
    			self.ShowDropDown()
    			skip = False
    		#end if
     
    		if self.dropdown.IsShown() :
    			if event.GetKeyCode() == wx.WXK_RETURN : # on appuye sur Entrée => le TextCtrl prend la valeur de l'item sélectionné
    				self.SetValueFromSelected()
    				skip = False
    			#end if
    			if event.GetKeyCode() == wx.WXK_ESCAPE : # on appuye sur Echap => on cache le dropdown
    				self.ShowDropDown(False)
    				skip = False
    			#end if
    		#end if
     
    		if skip :
    			event.Skip()
    		#end if
    	#end OnKeyDown
     
    	def OnListDClick(self,evt):
    		"Le TextCtrl prend la valeur de l'élément sur lequel on double-clique"
    		self.SetValueFromSelected()
    		evt.Skip()
    	#end OnListDClick
     
    	def SetChoices(self):
    		"Remplit la liste avec les éléments passés en entrée"
    		self.dropdownlistbox.InsertColumn(0,"")
     
    		for valeur in self.choix:
    			self.dropdownlistbox.InsertStringItem(sys.maxint,valeur)
    		#end for
     
    		self.SetListSize()
    	#end SetChoices
     
    	def SetListSize(self):
    		"Dimensionne la liste et le dropdown"
    		itemcount = min(len(self.choix),7 ) + 2
    		if itemcount < 6 : # pour éviter que la liste soit trop petite s'il n'y a rien dedans
    			itemcount = 6
    		#end if
     
    		charheight = self.dropdownlistbox.GetCharHeight()
    		self.popupsize = wx.Size(self.texte.GetSize()[0]+13,charheight*itemcount)
    		self.dropdownlistbox.SetSize(self.popupsize)
    		self.dropdown.SetSize(self.popupsize)
    	#end SetListSize
     
    	def SetValueFromSelected(self) :
    		"Le TextCtrl prend la valeur de l'item sélectionné"
    		sel = self.dropdownlistbox.GetFirstSelected()
    		if sel > -1:
    			itemtext = self.dropdownlistbox.GetItem(sel,0).GetText()
    			self.texte.SetValue(itemtext)
    			self.texte.SetInsertionPointEnd()
    			self.ShowDropDown(False)
    		#end if
    	#end SetValueFromSelected
     
    	def ShowDropDown (self,show=True) :
    		"Montre ou cache le dropdown suivant la variable show"
    		if show :
    			self.dropdown.SetSize((0,0))
    			self.dropdown.SetPosition((-2,19))
    		#end if
    		self.dropdown.Show(show)
    		if show :
    			self.SetListSize()
    		#end if
    	#end ShowDropDown
    #end Combo
    Désolé pour les #end machinchose , mais je codais principalement en html ou en php, et je dois avouer que sans ça, je suis un peu perdu dans le code.
    J'ai essayé de commenter un maximum (depuis que je me suis mis à Python, j'essaye de faire les choses bien... mais je sais pas combien de temps ça va durer encore ), mais si y a quelque chose d'obscur, n'hésite pas à demander.
    Idem s'il y a quelque chose qui ne va pas, qui pourrait être amélioré... Je suis preneur!
    Bon, en espérant t'avoir aidé (en tout cas, je me suis beaucoup aidé moi, et sans toi, je sais pas si j'aurais pu commencer, donc merci beaucoup)
    Ciao

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Bloquer la saisie semi automatique du navigateur
    Par Oluha dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 01/02/2007, 22h53
  2. Problème avec la saisie semi-automatique d'internet explorer
    Par haltabush dans le forum Balisage (X)HTML et validation W3C
    Réponses: 14
    Dernier message: 07/02/2006, 13h23
  3. Saisie semi automatique
    Par Necron dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 06/02/2006, 09h05
  4. Saisie semi-automatique
    Par kurul1 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 23/01/2006, 08h20
  5. Liste déroulante en saisie semi automatique
    Par pier07 dans le forum Composants VCL
    Réponses: 4
    Dernier message: 29/07/2005, 17h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo