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

Bibliothèques tierces Python Discussion :

[tkinter] redimensionnement fenêtre


Sujet :

Bibliothèques tierces Python

  1. #1
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut [tkinter] redimensionnement fenêtre
    Salut,

    j'ai une fenêtre qui contient 3 objets tk.Text et j'aimerais qu'un redimensionnement vertical de cette fenêtre se répercute sur le 3ème objet Text. Or on donne la hauteur de ces objets en nombre de lignes au lieu de pixels. Ce qui fait qu'un paramètre non maitrisé se rajoute, c'est la hauteur d'une ligne en fonction de la police. Dans le bout de code ci-dessous, la ligne 18 utilise empiriquement un diviseur de 16 pour redimensionner le tout... Y aurait une façon plus propre et plus universelle d'y arriver?

    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
     
    import Tkinter as tk
    import sys
     
    def addTextBox(parent, text, height, row):
        widget = tk.Text(parent, height=height)
        widget.insert('end', text)
        sbar = tk.Scrollbar(parent, orient='vertical')
        widget["yscrollcommand"] = sbar.set
        sbar['command']=widget.yview
        widget.grid(sticky='ew',column=0, row=row)
        sbar.grid(column=1, row=row, sticky='ns')
        widget.update_idletasks()
        return widget
     
    def resize(event):
        height = win.winfo_height() - win.offset
        win.widget['height'] = height / 16
        widget.update_idletasks()
     
    win = tk.Tk()
    text = open(sys.argv[0]).read(-1)
    # creates 3 Text objects
    for row, height in enumerate([6, 6, 20]):
        widget = addTextBox(win, text, height, row)
    # prepare data for resize
    win.widget = widget
    win.offset = win.winfo_height() - widget.winfo_height()
    win.bind('<Configure>', resize)
    # infinite loop
    win.resizable(height=True, width=False)
    win.mainloop()
    A+

    Pfeuh

  2. #2
    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
    Bonsoir pfeuh,

    Pour cela j'utilise 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
    21
    22
    import Tkinter as tk
    import sys
     
     
    def addTextBox(parent, text, height, exp):
        frm = tk.Frame(win)
        frm.pack(fill=tk.BOTH, expand=exp)
        widget = tk.Text(frm, height=height)
        widget.insert('end', text)
        sbar = tk.Scrollbar(frm, orient='vertical')
        widget["yscrollcommand"] = sbar.set
        sbar['command'] = widget.yview
        widget.pack(side=tk.LEFT, fill=tk.Y)
        sbar.pack(side=tk.LEFT, fill=tk.Y)
     
     
    win = tk.Tk()
    text = open(sys.argv[0]).read(-1)
    for height, exp in ((6, 0), (6, 0), (20, 1)):
        widget = addTextBox(win, text, height, exp)
    win.resizable(height=True, width=False)
    win.mainloop()
    @+
    Merci d'utiliser le forum pour les questions techniques.

  3. #3
    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
    La solution grid au passage:
    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
    import Tkinter as tk
    import sys
     
     
    def addTextBox(parent, text, height, row):
        widget = tk.Text(parent, height=height)
        widget.insert('end', text)
        sbar = tk.Scrollbar(parent, orient='vertical')
        widget["yscrollcommand"] = sbar.set
        sbar['command'] = widget.yview
        widget.grid(sticky='nsew', column=0, row=row)
        sbar.grid(column=1, row=row, sticky='nsew')
     
     
    win = tk.Tk()
    with open(sys.argv[0]) as source:
        text = source.read()
    # creates 3 Text objects
    for row, height in enumerate((6, 6, 20)):
        addTextBox(win, text, height, row)
    win.grid_rowconfigure(2, weight=1)  # <<<<
    # infinite loop
    win.resizable(height=True, width=False)
    win.mainloop()
    Mais cela s'applique à tous les Widgets de la column/du row (grid_columnconfigure/grid_rowconfigure)
    et il nécessaire de penser à l'utiliser pour les différents niveaux.
    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
    import Tkinter as tk
    import sys
     
     
    def addTextBox(parent, text, height, row, col):
        frm = tk.Frame(parent)
        frm.grid(column=col, row=row, sticky='nsew')
        widget = tk.Text(frm, height=height)
        widget.insert('end', text)
        sbar = tk.Scrollbar(frm, orient='vertical')
        widget["yscrollcommand"] = sbar.set
        sbar['command'] = widget.yview
        widget.grid(column=0, row=0, sticky='nsew')
        sbar.grid(column=1, row=0, sticky='nsew')
        frm.grid_rowconfigure(0, weight=1)
     
     
    win = tk.Tk()
    with open(sys.argv[0]) as source:
        text = source.read()
    # creates 6 Text objects
    for col in range(2):
        for row, height in enumerate((6, 6, 20)):
            addTextBox(win, text, height, row, col)
    win.grid_rowconfigure(2, weight=1)
    # infinite loop
    win.resizable(height=True, width=False)
    win.mainloop()
    Merci d'utiliser le forum pour les questions techniques.

  4. #4
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Merci pour cette réponse, c'est exactement ce que je cherchais. En plus, quand je t'ai vu utiliser "with open", j'ai eu le déclic sur le fonctionnement de cette commande.

    A+

    Pfeuh

  5. #5
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Autant j'arrive à me débrouiller avec un objet simple, autant j'ai du mal avec le widget Canvas... Mon but est d'afficher une liste d'objets avec une scrollbar, et de pouvoir modifier la hauteur de la fenêtre contenant la liste d'objets... Pas facile! Enfin, j'ai déjà un début dans le sens où le Labelframe contenant la liste s'ajuste bien aux changements de hauteur...

    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
     
    import Tkinter as tk
    import sys
     
    def buttonCallback(y, text):
        print "button %s[%i] pressed"%(text, y)
     
    def cellCallback(event, x, y, text):
        print "cell[%i, %i]=%s"%(x, y, text)
     
    class FIXED_OBJECT(tk.LabelFrame):
        def __init__(self, container, title='', text='', **kwds):
            tk.LabelFrame.__init__(self, container, text=title, **kwds)
            self.editor = tk.Text(self, **kwds)
            self.editor.insert('end', text)
            self.editor.grid(column=0, row=0, sticky='nsew')
            self.scrollbar = tk.Scrollbar(self, orient='vertical')
            self.scrollbar.grid(column=1, row=0, sticky='ns')
            self.editor['yscrollcommand'] = self.scrollbar.set
            self.scrollbar.config(command=self.editor.yview)
     
    class RESIZABLE_OBJECT(tk.LabelFrame):
        def __init__(self, container, title='', data=None, **kwds):
            tk.LabelFrame.__init__(self, container, text=title, **kwds)
            self.canvas = tk.Canvas(self, height=250)
            self.frm = tk.Frame(self.canvas)
            self.canvas.create_window(0, 0, window=self.frm)
            self.placeData(data)
            self.frm.grid()
            self.canvas.grid(column=0, row=0, sticky='nsew')
            self.scrollbar = tk.Scrollbar(self, orient='vertical')
            self.scrollbar.grid(column=1, row=0, sticky='ns')
            self.canvas['yscrollcommand'] = self.scrollbar.set
            self.scrollbar['command'] = self.canvas.yview
     
        def placeData(self, data):
            for y, line in enumerate(data):
                if y & 1:
                    color = 'green'
                else:
                    color = 'white'
                for x in range(6):
                    if x < len(line):
                        cell = line[x]
                    else:
                        cell = '. . . .'
                    cellgui = tk.Label(self.frm, text=cell, width=16, bg=color, cursor='hand2')
                    cellgui.grid(column=x, row=y)
                    cellgui.bind("<Button-1>", lambda event=None, x=x, y=y, label2=cell:cellCallback(event, x, y, label2))
                tk.Button(self.frm, text='read', width=3, command=lambda y=y, label='read':buttonCallback(y, label)).grid(column=6, row=y)
                tk.Button(self.frm, text='write', width=3, command=lambda y=y, label='write':buttonCallback(y, label)).grid(column=7, row=y)
     
    class WINDOW(tk.Toplevel):
        def __init__(self, container, *args, **kwds):
            tk.Toplevel.__init__(self, container, *args, **kwds)
            with open(sys.argv[0]) as fp:
                default_text= fp.read(-1)
            with open(sys.argv[0]) as fp:
                lines= fp.readlines()[:30]
            data = [line.split()[:5] for line in lines]
            self.widget1 = FIXED_OBJECT(self, title='RAW PDO', text=default_text, width=40, height=2)
            self.widget2 = FIXED_OBJECT(self, title='PDO OBJECTS', text=default_text, width=80, height=4)
            self.widget3 = RESIZABLE_OBJECT(self, "EDS OBJECTS", data)
            self.widget1.grid()
            self.widget2.grid()
            self.widget3.grid(sticky='nsew')
            self.grid_rowconfigure(2, weight=1)
            self.offset = self.winfo_height() - self.widget3.canvas.winfo_height()
            self.resizable(height=True, width=False)
     
    if __name__ == "__main__":
     
        win = tk.Tk()
        node = WINDOW(win)
        win.mainloop()
    A+

    Pfeuh

  6. #6
    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,

    En fait je ne comprend pas ce jeu de matriochkas: LabelFrame > Canvas > Frame avec un .create_window().
    Pourquoi utiliser self.canvas et non directement self.frm ? Après tout c'est lui qui nous intéresses (Du moins dans placeData).
    Note: Rien n'interdit de mixer les géométry manager si ce n'est pas pour un même niveau de widget et que cela apporte un avantage.

    @+
    Merci d'utiliser le forum pour les questions techniques.

  7. #7
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Citation Envoyé par PauseKawa Voir le message
    Pourquoi utiliser self.canvas et non directement self.frm ?
    Parce qu'il me semble que c'est la seule façon de gérer une scrollbar pour les lignes de data. J'ai toujours trouvé ça lourd, mais je ne sais pas comment faire autrement. je viens de vérifier, l'objet Frame n'a pas de yscrollcommand.

  8. #8
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Suite à tes précieux conseils, j'ai réussi à rendre un canvas redimensionable... Entre parenthèse que c'est compliqué de faire du code simple! Je pense que toute l'astuce est dans le sheet['scrollregion'] par contre pour quelque chose comme mon placeData, qui utilise grid, impossible d'arriver au même résultat. Je continue quand même.

    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
     
    import Tkinter as tk
    import random as random
    import sys
    colors = ['red', 'blue', 'green', 'yellow']
     
    def drawEllipses(widget):
        for iter in range(200):
            x1 = random.randrange(0, 2000)
            y1 = random.randrange(0, 2000)
            x2 = x1 + random.randrange(100, 300)
            y2 = y1 + random.randrange(100, 300)
            idx_color = random.randrange(0, 4)
            widget.create_oval(x1, y1, x2, y2, fill=colors[idx_color])
     
    def getScrollableObject(parent):
        sheet = tk.Canvas(parent)
        drawEllipses(sheet)
        sbarv = tk.Scrollbar(parent,command=sheet.yview)
        sbarh = tk.Scrollbar(parent,command=sheet.xview, orient='horizontal')
        sheet.grid(column=0, row=0, sticky='nsew')
        sbarv.grid(column=1, row=0, sticky='ns')
        sbarh.grid(column=0, row=1, sticky='ew')
        sheet['yscrollcommand'] = sbarv.set
        sheet['xscrollcommand'] = sbarh.set
        sbarv['command'] = sheet.yview
        sbarh['command'] = sheet.xview
        sheet['scrollregion'] = sheet.bbox("all")
     
    win = tk.Tk()
    getScrollableObject(win)
    win.grid_rowconfigure(0, weight=1)
    win.grid_columnconfigure(0, weight=1)
    win.mainloop()

Discussions similaires

  1. [Tkinter] Redimensionner une Listbox
    Par THE_VIP dans le forum Tkinter
    Réponses: 6
    Dernier message: 29/05/2008, 17h36
  2. Redimensionnement fenêtre en fonction d'une image
    Par skyjoe dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 17/12/2006, 13h54
  3. [Tkinter] Plusieurs fenêtre avec Tkinter
    Par cyrpaut dans le forum Tkinter
    Réponses: 2
    Dernier message: 04/01/2006, 22h24
  4. redimensionnement fenêtre
    Par Triomen dans le forum Windows
    Réponses: 6
    Dernier message: 08/02/2005, 00h54
  5. [BPW] Affichage clignotant lors de redimensionnement fenêtre
    Par Alcatîz dans le forum Turbo Pascal
    Réponses: 10
    Dernier message: 24/04/2004, 00h01

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