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

Tkinter Python Discussion :

Line width d'un widget tkinter text s'agrandissant avec la fenetre


Sujet :

Tkinter Python

  1. #1
    Membre confirmé
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Par défaut Line width d'un widget tkinter text s'agrandissant avec la fenetre
    Bonjour, je souhaite récupérer la longueur de ligne d'un widget texte tkinter lorsque je modifie la taille de la fenetre qui le contient.

    Le widget texte est configuré pour s'agrandir avec la fenêtre quand on en modifie la taille (j'ai essayé avec grid ou pack) et si je récupère la longueur de ligne du widget, celle ci reste toujours la même alors que j'ai changé la taille du widget en redimensionnant la fenetre qui le contient.

    Comment récupérer la largeur (width) du widget texte (en nombre de caractères) quand celui ci est surdimensionné à la souris?

    merci d'avance

    PS: voici un exemple:

    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
     
    # -*- coding:Latin-1 -*-
     
    #####################
    # imports
    from Tkinter import *
    from ScrolledText import *
     
    ##########
    #Interface
    def line_width():
        print txt.cget("width")
     
    root = Tk()
    txt = ScrolledText(root, width=50, font="courier")
    txt.pack()#expand=1, fill="both")
    but = Button(root, text="print line width", command=line_width)
    but.pack()
     
    root.mainloop()

  2. #2
    Membre expérimenté Avatar de Gaillac
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2008
    Messages : 165
    Par défaut
    Au vue de ton code je ne vois pas en quoi ta zone de texte est redimensionnée, ni en largeur ni en hauteur.

  3. #3
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    J'ai essayé aussi avec le widget Text de Tkinter, en utilisant la méthode du manuel Tkinter de Mexico pour qu'il soit redimensionné avec la fenêtre (et ça marche: http://python.jpvweb.com/mesrecettespython/texte_redim),

    Mais je n'arrive pas non plus à obtenir une mise à jour de la nouvelle largeur du widget Text en nombre de caractères.

    Ce serait bien si quelqu'un avait une solution.

    Tyrtamos

  4. #4
    Membre confirmé
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Par défaut
    Citation Envoyé par Gaillac Voir le message
    Au vue de ton code je ne vois pas en quoi ta zone de texte est redimensionnée, ni en largeur ni en hauteur.
    oui désolé, j'avais commenté le redimensionnement avec pack:

    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
     
    # -*- coding:Latin-1 -*-
     
    #####################
    # imports
    from Tkinter import *
    from ScrolledText import *
     
    ##########
    #Interface
    def line_width():
        print txt.cget("width")
     
    root = Tk()
    txt = ScrolledText(root, width=50, font="courier")
    txt.pack(expand=1, fill="both")
    but = Button(root, text="print line width", command=line_width)
    but.pack()
     
    root.mainloop()
    Et comme Tyrtamos l'a aussi remarqué, la valeur width du widget ScrolledText n'est pas mise à jour lorsque l'on modifie la taille de la fenêtre à la souris. Quelqu'un connait-il un moyen de faire cela ou même de le calculer en fonction de la taille du widget en pixel (récupérée par winfo_geometry() par exemple) en fonction de la police utilisée?

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Voilà une solution:

    Pour récupérer la longueur et la hauteur du widget en pixels après le redimensionnement de la fenêtre:

    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 *
    from ScrolledText import *
     
    larg=None
    haut=None
     
    def line_width(event):
        global larg, haut
        larg = event.width
        haut = event.height
        print larg, haut 
     
    root = Tk()
    txt = ScrolledText(root, width=50, font='Courier')
    txt.pack(expand=1, fill="both")
    txt.bind("<Configure>", line_width)
    root.mainloop()
    Comme cette largeur est en pixels, on peut faire comme cela:

    - on importe le module tkFont
    - on définit la police qu'on veut de cette façon (il y a d'autres options):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    police=tkFont.Font(size=12, family='Courier')
    ...
    txt = ScrolledText(root, width=50, font=police)
    ...
    On peut maintenant demander la longueur en pixels d'un texte donné écrit avec la police définie:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    test="que j'aime à faire apprendre un nombre utile aux sages"
    lpix = police.measure(test)
    moy = lpix/len(test)
    Ce qui est facile ici, puisqu'avec la police 'courrier', chaque caractère tient la même place (le 'i' et le 'w' par exemple).

    Par contre, avec d'autres polices comme Arial ou helvetica, ce n'est plus vrai, et le résultat en pixels sera une valeur unique pour la phrase donnée. Cependant, si la phrase est assez longue, on devrait obtenir une moyenne utilisable (et en français, puisque la fréquence des lettres change selon la langue!)

    Infos complémentaires:

    - police.metrics() donne des infos sur la police, et en particulier si elle est fixe comme courier. Par exemple: {'fixed': 1, 'ascent': 14, 'descent': 4, 'linespace': 18}. Les autres infos donnent les interlignes.
    - tkFont.families() donne toutes les "fonts" auxquelles on a droit sur l'OS (c'est une très longue liste Python).

    Ok?

    Tyrtamos

  6. #6
    Membre confirmé
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Par défaut
    Oui, c'est en effet ce que j'ai fait suite à votre réponse sur "comment lancer une commande lors du redimensionnement".

    Dans mon cas, c'est plutôt simple dans le sens où j'utilise une police à taille fixe (courier), donc j'ai fait simple, mais le problème a été de faire le calcul inverse, c'est à dire de calculer le nombre de caractères en fonction de la taille de mon ScrolledText. Après avoir bidouillé, j'ai pu trouver qu'il fallait que je retire de la taille de mon ScrolledText 6 pixels pour retomber à chaque fois sur la taille prédite par ma méthode "measure" de la police (ici la taille du caractère est de 12 pixels en large).

    Çà a l'air de marcher maintenant et au pixel près, line width est ajustée lorsque je redimensionne la fenetre : Voir l'exemple, un peu brouillon mais on voit vite que ca marche

    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
    # -*- coding:Latin-1 -*-
     
    from Tkinter import *
    from ScrolledText import *
    import tkFont
    def mafunc(event):
        print "width cget;"
        print txt.cget("width")
        print "calcul"
        print int((txt.winfo_width()-6)/12)
        nouv = int((txt.winfo_width()-6)/12)
        #nouv = nouv + 1
        txt.configure(width=nouv)
    root = Tk()
    myfont = tkFont.Font(root, family='Courier')
    txt = ScrolledText(root, width=40, font=myfont)
    txt.insert(END, "1234567890123456789012345678901234567890")
    txt.pack(fill=X)
    print "measure 40", myfont.measure("1234567890123456789012345678901234567890")
    print "width txt:", txt.winfo_width()
    root.bind("<Configure>", mafunc)
    root.mainloop()
    Merci encore, il ne me reste plus qu'à régler mon problème de scrolling quand le scrolledtext n'a qu'un seule longue ligne et je pourrai avancer mon programe...

    PS : après mutiples essais sur différents ordianteurs, il semble que cela dépende de la résolution car sur mon portable ou j'ai effectué les tests, je suis en 120ppp et ca marche ; alors que sur mon ordi de buerau en 96 ppp, le calcul est faut et doit etre ajusté.

  7. #7
    Membre confirmé
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Par défaut
    Voilà un code qui prend en compte automatiquement la résolution ppp:

    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
    # -*- coding:Latin-1 -*-
     
    from Tkinter import *
    from ScrolledText import *
    import tkFont
    def mafunc(event):
        nouv = int((txt.winfo_width()-dif_pixel)/ratio)
        print nouv
        txt.configure(width=nouv)
    root = Tk()
    myfont = tkFont.Font(root, family='Courier')
    txt = ScrolledText(root, width=40, font=myfont)
    txt.insert(END, "1234567890123456789012345678901234567890")
    txt.pack(fill=X)
    calcul = myfont.measure("1234567890123456789012345678901234567890")
    print "Taille 40 chars :", calcul
    mesure = txt.winfo_width()
    print "width txt :", mesure
    dif_pixel = mesure - calcul
    print "différence taille :", dif_pixel
    ratio = calcul/40
    print "ratio", ratio
    root.bind("<Configure>", mafunc)
    root.mainloop()

  8. #8
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    Salut, j'ai pas tout lu, mais t'as essayé de faire un widget.update_idletasks() avant d'essayer de récupérer la valeur width du widget text ? Peut-être que la requête d'information du width s'effectue alors que la fenêtre n'est pas encore affichée, ce que la commande sus-citée devrait forcer ; enfin, si j'ai correctement identifier la source de la non-actualisation...

  9. #9
    Membre confirmé
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Par défaut
    Bonjour, oui j'avais essayé mais cela ne fonctionne pas :

    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
    # -*- coding:Latin-1 -*-
     
    #####################
    # imports
    from Tkinter import *
    from ScrolledText import *
     
    ##########
    #Interface
    def line_width():
        txt.update_idletasks()
        root.update_idletasks()
        print txt.cget("width")
     
    root = Tk()
    txt = ScrolledText(root, width=50, font="courier")
    txt.pack(expand=1, fill="both")
    but = Button(root, text="print line width", command=line_width)
    but.pack()
     
    root.mainloop()
    Merci quand même.

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

Discussions similaires

  1. Tkinter.Text get last line
    Par ____22 dans le forum Tkinter
    Réponses: 0
    Dernier message: 30/08/2010, 12h43
  2. deplacer le curseur dans un Tkinter.Text
    Par pfeuh dans le forum Tkinter
    Réponses: 2
    Dernier message: 18/03/2009, 14h12
  3. effacer le contenu d'un Tkinter.Text
    Par Wael Maaoui dans le forum Tkinter
    Réponses: 1
    Dernier message: 26/03/2007, 17h20
  4. [Tkinter]Text: récupération de données.
    Par airod dans le forum Tkinter
    Réponses: 2
    Dernier message: 10/01/2006, 11h15

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