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

Python Discussion :

limiter la saisie de lignes avec widget text ?


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 12
    Points : 11
    Points
    11
    Par défaut limiter la saisie de lignes avec widget text ?
    Question toute simple que je me pose.
    j'ai fait un programme qui utilise la bibliothèque reportlab, le but
    étant de créer un un document pdf.
    Dans le programme l'utilisateur est amené à saisir du texte.
    Je veux laisser la possibilité à l'utilisateur de rentrer 5 lignes de
    texte de son choix.
    5 lignes et pas 6 !
    avec une ligne comprenant maxi 80 caractères.
    Le widget text semble répondre à ces attentes:

    from Tkinter import *
    root=Tk()
    txt=Text(root,width=80,height=5) # 80 caractères et 5 lignes
    txt.pack()

    root.mainloop()

    Mais, il y a un petit problème, si l'utilisateur veut taper plus de 5
    lignes, il le peut, rien ne l'en empèche.
    D'ou ma question: Comment empécher la saisie d'une 6 eme ligne, d'une
    7eme ligne .. ?
    Si vous avez une petite idée?

    P.S
    La solution consistant à cliquer sur un bouton "ok" qui génèrerait un message d'erreur ne me satisfait pas:
    Solution genre sauvegarder le texte puis par une petite procédure compter le nombre de lignes et si ce nbre de lignes est > à 5 j'affiche un message
    d'erreur.
    Mais ce n'est pas ce que je recherche, je veux un contrôle permanent
    sans que l'utilisateur ai besoin de cliquer sur "ok".
    Un contrôle qui empêche la saisie de la 6eme ligne au moment même ou
    l'utilisateur fait son "retour chariot".
    Un peu comme la fonction validate de Pmw.EntryField qui permet de
    limiter l'entrée au moment même de la saisie.
    P.s j'ai regardé chez Pmw , en particulier Pmw.ScrolledText et je n'ai
    rien vu pouvant m'aider .

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2008
    Messages : 76
    Points : 94
    Points
    94
    Par défaut
    Salut !

    Ce n'est sans doute pas la meilleure solution, mais tu peux surveiller les événements et détecter si l'utilisateur appuie sur enter/return. Si c'est le cas, tu incrémentes un compteur et tu testes que cette valeur ne dépasse pas cinq...
    Vraiment, je ne suis qu'a moitié convaincu mais je n'ai pas trouvé d'autres événements ou méthodes pour faire ce comportement. (Faut passer à wxpython )

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 12
    Points : 11
    Points
    11
    Par défaut petite piste exploitant tes remarques mais pas la soluce tout de même
    Exemple de soluce incomplète, on informe bien que l'on a dépassé le nbre maxi de lignes mais hélas l'utilisateur un peu neuneu peut tout de même dépasser le nbre maxi autorisé.

    J'ai utilisé un thread qui me permet de savoir à quel moment on atteind les 15 lignes. Mais ça ne bloque pas la saisie,... hélas!!
    si vous avez une idée..., je suis preneur

    Pour la commodité j'ai limité la saisie à 15 lignes, la dernière ligne devant être "JDEF votre serviteur"

    #!/usr/bin/env python
    # -*- coding: cp1252 -*-
    #Remarque codage en cp1252 sur python2.4 et sur linux python2.6 on est en utf-8
    #
    #Prog test par J.Def du widget text de Tkinter
    #But : Informer l'utilisateur lorsqu'il dépasse le nbre maxi de lignes (ici 15)
    #Méthode trouvé: utilisation d'un Thread
    #
    #PB Je l'informe dès qu'il a dépassé les 15 lignes saisies, mais hélas je ne l'empêche pas
    #de saisir plus de 15 lignes!
    #La question reste entière : comment bloquer la saisie au dela des 15 lignes ??

    from Tkinter import *
    import threading,time

    def fct(): #appelé par le thread, dès que l'on a + de 15 lignes on met une alarme
    global stop,f_alarm
    while stop==0:
    time.sleep(0.01)

    start = 1.0
    while 1: #je scrute la dernière ligne censée être la signature du document: JDEF votre serviteur
    pos = txt.search("JDEF votre serviteur", start, stopindex=END)
    if not pos:
    break
    nb_ligne=int(eval(pos))
    print "le nbre de lignes est",nb_ligne
    start = pos + "+1c"
    if nb_ligne>15: #si supérieur à 15 lignes -> envoie l'alarme
    stop=1 #stope le thread
    f_alarm=Toplevel()
    l=Label(f_alarm,text="vous ne devez pas dépasser 15 lignes").pack()


    def quit():
    global stop,root
    stop=1
    root.destroy()


    #--------------- prog principal -------------------------
    root=Tk()
    root.geometry("%dx%d+%d+%d" % (300,300,0,0))
    txt=Text(root,width=40,height=15)
    txt.pack()

    #mise en place de la signature de bas de page:
    txt.insert(END, "\n\n\n\n\nJDEF votre serviteur")


    button = Button(root, text="quit", command=quit).place(x=150,y=250)

    #on lance le thread:
    t = threading.Thread(target=fct)
    stop=0
    t.start()

  4. #4
    Membre confirmé
    Avatar de vincent.mbg
    Homme Profil pro
    Développeur Python
    Inscrit en
    Décembre 2007
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Python

    Informations forums :
    Inscription : Décembre 2007
    Messages : 327
    Points : 618
    Points
    618
    Par défaut
    Bonjour

    En fait il faut binder une fonction qui va briser l'événement par défaut de Tk
    en retournant la chaine "break"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
        self.bind( "<Key-Return>",  self.return   )
            [...]
        def return( self, event ) :
                text = self.get()
                # si text contien 5 "\n" :
                         # affiche message "pas plus de 5 lignes SVP.
                        return "break"

  5. #5
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    L'idée du bind de vincent.mbg est bonne.
    Avec l'index cela fonctionne.

    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
    from Tkinter import *
     
    def monevent(event) :
        if int(txt.index(INSERT)[0]) > 5:
            txt.delete(6.0, END)
     
    def quit():
        global stop,root
        stop=1
        root.destroy()
     
    root=Tk()
    root.geometry("%dx%d+%d+%d" % (300,300,0,0))
    txt=Text(root,width=40,height=15)
    txt.pack()
    root.bind( "<Key-Return>", monevent)
    button = Button(root, text="quit", command=quit).place(x=150,y=250)
    root.mainloop()
    Même principe pour le nombre de caractère.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int(txt.index(INSERT)[2]) > 80
    @+

    Oups, petit edit : [2] et pas [1] bien sur

  6. #6
    Membre confirmé
    Avatar de vincent.mbg
    Homme Profil pro
    Développeur Python
    Inscrit en
    Décembre 2007
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Python

    Informations forums :
    Inscription : Décembre 2007
    Messages : 327
    Points : 618
    Points
    618
    Par défaut
    Bonjour

    Il y a une faille
    On peut toujours ajouter plus de 5 lignes il suffit pour ça d'ajouter une ligne par le milieu.

    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
    def monevent(event) :
        lignes = txt.get( 0.0,  'end')
        nmb_cr = lignes.count('\n')
        if nmb_cr >= 5:
            return "break" # Casser la pile d'événement.
        
    def quit():
        global stop,root
        stop=1
        root.destroy()
     
    root=Tk()
    root.geometry("%dx%d+%d+%d" % (300,300,0,0))
    txt=Text(root,width=40,height=15) 
    txt.pack()
    txt.bind( "<Key-Return>", monevent) # Binder sur txt car seul lui est concerné
    button = Button(root, text="quit", command=quit).place(x=150,y=250)
    root.mainloop()

    je conseille vraiment le qui permet que rien ne sois fait à la place de laisser faire quelque chose pour le défaire.

    Une autre métode consiste à un mettre un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    root.unbind_class ( "Text", "<Return>")
    et a créé une fonction qui ajoute ou non un retour à la ligne.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 12
    Points : 11
    Points
    11
    Par défaut félicitations à vous tous !
    Je butais sans voir de solution.
    Vous avez parfaitement répondu à mon pb.
    L'idée du bind était bien la solution.

    Merci à vous tous. Je savais bien qu'il y avait des programmeurs de grande classe sur ce site.
    jérôme

  8. #8
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Citation Envoyé par vincent.mbg Voir le message
    Il y a une faille
    On peut toujours ajouter plus de 5 lignes il suffit pour ça d'ajouter une ligne par le milieu.
    Bien vu

    Edit: Début de réponse (il reste du travail...) sur mon idée.

    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
    #!/usr/bin/env python
    # -*- coding: ISO8859-1 -*-
    #
    #
    from Tkinter import *
     
    def monevent(event):
        global textfin
        if int(txt.index(END)[0]) > 7:
            txt.delete(0.0, END)
            txt.insert(0.0, textfin)
        textfin = txt.get(0.0, 6.0)
     
     
    def quit():
        root.destroy()
     
    root=Tk()
    root.geometry("%dx%d+%d+%d" % (300,300,0,0))
    txt=Text(root,width=40,height=15)
    txt.pack()
    root.bind( "<Key-Return>", monevent)
    button = Button(root, text="quit", command=quit).place(x=150,y=250)
    root.mainloop()

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 12
    Points : 11
    Points
    11
    Par défaut Ma soluce au pb de limitation des lignes du widget text
    Après m'être inspiré de vos remarques et soluces, je vous donne ma version d'un petit programme qui répond à mes attentes : voir le fichier joint
    Si ça peut modestement aider quelqu'un confronté au même problème.

    Encore merci pour toute votre aide

    ohtoulouse
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. Comment limiter la saisie à deux décimales dans mon widget Text ?
    Par Nicolas Dansel dans le forum SWT/JFace
    Réponses: 3
    Dernier message: 09/09/2009, 16h13
  2. Sauter des lignes avec du texte Qt
    Par Kaluza dans le forum Code::Blocks
    Réponses: 0
    Dernier message: 15/07/2009, 06h26
  3. [AC-2003] Limiter la saisie d'une zone de texte à des chiffres
    Par aymane19 dans le forum VBA Access
    Réponses: 5
    Dernier message: 30/04/2009, 19h10
  4. Saisie nouvelle ligne dans fichier texte
    Par maverick91 dans le forum VBA Access
    Réponses: 2
    Dernier message: 26/08/2008, 15h02
  5. Probleme avec widget Text
    Par will97 dans le forum Tkinter
    Réponses: 4
    Dernier message: 16/03/2007, 21h58

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