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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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

+ 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