Comment limiter la saisie de lignes sur le widget text

Le
jerome defrancais
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?
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Amaury Forgeot d'Arc
Le #21091631
Le 30/01/2010 17:53, jerome defrancais a écrit :
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?



Un message d'erreur quand il tente d'appuyer sur OK?

--
Amaury
jerome defrancais
Le #21091981
On 30 jan, 18:33, Amaury Forgeot d'Arc
Le 30/01/2010 17:53, jerome defrancais a écrit :

> 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?

Un message d'erreur quand il tente d'appuyer sur OK?

--
Amaur




je sais ou tu veux en venir, en cliquant sur un bouton "ok", je
sauvegarde le texte puis par une petite procédure je compte 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 .
jerome defrancais
Le #21093901
On 30 jan, 18:53, jerome defrancais
On 30 jan, 18:33, Amaury Forgeot d'Arc
> Le 30/01/2010 17:53, jerome defrancais a écrit :

> > 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'u ne
> > 7eme ligne .. ?
> > Si vous avez une petite idée?

> Un message d'erreur quand il tente d'appuyer sur OK?

> --
> Amaur

je sais ou tu veux en venir, en cliquant sur un bouton "ok", je
sauvegarde le texte puis par une petite procédure je compte 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 o u
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 .




J'ai bien pensé à utiliser à un thread, mais si ça informe bien
l'utilisateur, ça ne bloque pas la saisie, hélas!!
si vous avez une idée pour améliorer le bazard je suis preneur
dans le petit script ci-dessous, 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 signatur e
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@,height)
txt.pack()

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


button = Button(root, text="quit", command=quit).place(x0,y% 0)

#on lance le thread:
t = threading.Thread(targetüt)
stop=0
t.start()
eb303
Le #21103091
On Jan 31, 1:05 am, jerome defrancais
On 30 jan, 18:53, jerome defrancais


> On 30 jan, 18:33, Amaury Forgeot d'Arc
> > Le 30/01/2010 17:53, jerome defrancais a écrit :

> > > 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?

> > Un message d'erreur quand il tente d'appuyer sur OK?

> > --
> > Amaur

> je sais ou tu veux en venir, en cliquant sur un bouton "ok", je
> sauvegarde le texte puis par une petite procédure je compte 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'a i
> rien vu pouvant m'aider .

J'ai bien pensé à utiliser à un thread, mais si ça informe bien
l'utilisateur, ça ne bloque pas la saisie, hélas!!
si vous avez une idée pour améliorer le bazard je suis preneur
dans le petit script ci-dessous, 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 me t
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 l a 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épasse r 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@,height)
txt.pack()

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

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

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



Faire ça par un thread est a priori une très mauvaise idée. D'une
part, Tkinter, comme la plupart des toolkits graphiques, n'apprécie en
général vraiment pas de se faire manipuler à partir de threads
différents. D'autre part, c'est franchement overkill: il y a tout ce
qu'il faut dans tk/Tkinter pour limiter le nombre de ligne d'un texte.

L'idée est simplement de vérifier à chaque fois que l'utilisateur
appuie sur une touche qu'il ne dépasse pas le nombre de ligne
autorisé. Par exemple:

-8<-----------
from Tkinter import *

root = Tk()
txt = Text(root)
txt.pack()

def restrict_lines(event):
last_line = int(txt.index(END).split('.')[0])
if last_line > 6:
return 'break'
else:
return 'continue'

txt.bind('<KeyPress>', restrict_lines)

root.mainloop()
----------->8-

A chaque appui sur une touche (pas <KeyRelease>, qui est le
relâchement de la touche, parce que là c'est trop tard), on appelle la
fonction restrict_lines, qui va chercher le nombre de ligne dans le
texte et empêche le binding "normal" de la touche de se déclencher si
on a atteint le nombre max en faisant: return 'break'. A noter qu'il y
a un décalage de 1 dans la limite (last_line > 6) parce que je calcule
la dernière ligne en récupérant celle du marqueur END, qui donne en
fait non pas la dernière ligne, mais en quelque sorte la première qui
n'existe pas.

HTH
|-| /-\\ |_ \(\)7 [°¿°]
Le #21106621
Bonsoir !

Puis-je proposer une solution sous Windows ?

Il faut d'abord créer le fichier saisi.htm qui contiendra :

========================================== <html><body bgColor=#ffffcc scroll=no>
Saisir <b>5 lignes maxi</b> :<br>
<textarea id="EDIT" rows="5" cols="72" name="EDIT"
wrap="no"></textarea><br><br>
<div alignÎnter>
<input id='BTOK' onclick='etat="OK";' type=button value=' &nbsp; &nbsp;
OK &nbsp; &nbsp; ' />
&nbsp; &nbsp;
<input id='BTANNUL' onclick='etat="ANNUL";' type=button value=' Annuler
' />
&nbsp; &nbsp;
</div>
<script language="JavaScript">
etat="DEBUT";
hedit=document.getElementById("EDIT");
hedit.focus();
</script>
</body></html>
==========================================
Mettre ce fichier, saisi.htm dans le même dossier que ce script :

# -*- coding: utf-8 -*-

def sai(nblmax=5):
import os,time,win32com.client
ie=win32com.client.Dispatch('InternetExplorer.Application')
ie.ToolBar = False
ie.AddressBar = False
ie.MenuBar = False
ie.StatusBar = False
ie.Left = 100
ie.Top = 20
ie.Width = 640
ie.Height = 220
ie.Visible = True
ie.Navigate(os.getcwd()+'\saisi.htm')
win = ie.Document.parentWindow
hdata = win.hedit
data=None
while True:
temp = hdata.innerText
temp = temp.replace('r','')
atemp = temp.split("n")
if len(atemp)>nblmax:
win.alert("Attention : "+str(nblmax)+" lignes maxi.")
hdata.innerText = 'rn'.join(atemp[:nblmax])
if win.etat == "OK":
data = hdata.innerText
break
if win.etat == "ANNUL":
break
time.sleep(0.128)
ie.Quit()
ie=None
return data

print sai(nblmax=5)



Yapuka-tester...

@+
--
Michel Claveau
Michel Claveau - NoSpam SVP ; merci
Le #21115171
Bonsoir !

Puis-je proposer une solution sous Windows ?

Il faut d'abord créer le fichier saisi.htm qui contiendra :

<html><body bgColor=#ffffcc scroll=no>
Saisir <b>5 lignes maxi</b> :<br>
<textarea id="EDIT" rows="5" cols="72" name="EDIT"
wrap="no"></textarea><br><br>
<div alignÎnter>
<input id='BTOK' onclick='etat="OK";' type=button value='
&nbsp; &nbsp;
OK &nbsp; &nbsp; ' />
&nbsp; &nbsp;
<input id='BTANNUL' onclick='etat="ANNUL";' type=button
value=' Annuler
' />
&nbsp; &nbsp;
</div>
<script language="JavaScript">
etat="DEBUT";
hedit=document.getElementById("EDIT");
hedit.focus();
</script>
</body></html>


Mettre ce fichier, saisi.htm , dans le même dossier que ce script :

# -*- coding: utf-8 -*-

def sai(nblmax=5):
import os,time,win32com.client
ie=win32com.client.Dispatch('InternetExplorer.Application')
ie.ToolBar = False
ie.AddressBar = False
ie.MenuBar = False
ie.StatusBar = False
ie.Left = 100
ie.Top = 20
ie.Width = 640
ie.Height = 220
ie.Visible = True
ie.Navigate(os.getcwd()+'\saisi.htm')
win = ie.Document.parentWindow
hdata = win.hedit
data=None
while True:
temp = hdata.innerText
temp = temp.replace('','')
atemp = temp.split("")
if len(atemp)>nblmax:
win.alert("Attention : "+str(nblmax)+" lignes maxi.")
hdata.innerText = ''.join(atemp[:nblmax])
if win.etat == "OK":
data = hdata.innerText
break
if win.etat == "ANNUL":
break
time.sleep(0.128)
ie.Quit()
ie=None
return data

print sai(nblmax=5)



Yapuka-tester...

@-salutations

Michel Claveau
Michel Claveau - NoSpam SVP ; merci
Le #21115281
Bonsoir !

Puis-je proposer une solution sous Windows ?

Il faut d'abord créer le fichier saisi.htm qui contiendra :

<html><body bgColor=#ffffcc scroll=no>
Saisir <b>5 lignes maxi</b> :<br>
<textarea id="EDIT" rows="5" cols="72" name="EDIT"
wrap="no"></textarea><br><br>
<div alignÎnter>
<input id='BTOK' onclick='etat="OK";' type=button value='
&nbsp; &nbsp;
OK &nbsp; &nbsp; ' />
&nbsp; &nbsp;
<input id='BTANNUL' onclick='etat="ANNUL";' type=button
value=' Annuler
' />
&nbsp; &nbsp;
</div>
<script language="JavaScript">
etat="DEBUT";
hedit=document.getElementById("EDIT");
hedit.focus();
</script>
</body></html>


Mettre ce fichier, saisi.htm , dans le même dossier que ce script :

# -*- coding: utf-8 -*-

def sai(nblmax=5):
import os,time,win32com.client
ie=win32com.client.Dispatch('InternetExplorer.Application')
ie.ToolBar = False
ie.AddressBar = False
ie.MenuBar = False
ie.StatusBar = False
ie.Left = 100
ie.Top = 20
ie.Width = 640
ie.Height = 220
ie.Visible = True
ie.Navigate(os.getcwd()+'\saisi.htm')
win = ie.Document.parentWindow
hdata = win.hedit
data=None
while True:
temp = hdata.innerText
temp = temp.replace('','')
atemp = temp.split("")
if len(atemp)>nblmax:
win.alert("Attention : "+str(nblmax)+" lignes maxi.")
hdata.innerText = ''.join(atemp[:nblmax])
if win.etat == "OK":
data = hdata.innerText
break
if win.etat == "ANNUL":
break
time.sleep(0.128)
ie.Quit()
ie=None
return data

print sai(nblmax=5)



Yapuka-tester...

@-salutations

Michel Claveau
BertrandB
Le #21148061
Michel Claveau - NoSpam SVP ; merci a écrit :
Bonsoir !

Puis-je proposer une solution sous Windows ?






une fois ça va trois fois bonjour les dégâts ;-)
Publicité
Poster une réponse
Anonyme