Précédent   Forum du club des développeurs et IT Pro > Autres langages > Python & Zope > Bibliothèques tierces
Bibliothèques tierces Forum d'entraide pour les autres bibliothèques non présentes dans la distribution standard de Python
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 31/10/2012, 16h03   #1
pfeuh
Membre Expert
 
Développeur en systèmes embarqués
Inscription : mars 2006
Messages : 763
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

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

Informations forums :
Inscription : mars 2006
Messages : 763
Points : 1 031
Points : 1 031
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 :
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
pfeuh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/10/2012, 19h47   #2
PauseKawa
Expert Confirmé
 
Avatar de PauseKawa
 
Homme Patrice BLANGARIN
Technicien Help Desk, maintenance, réseau, système et +
Inscription : juin 2006
Messages : 2 613
Détails du profil
Informations personnelles :
Nom : Homme Patrice BLANGARIN
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 613
Points : 3 724
Points : 3 724
Bonsoir pfeuh,

Pour cela j'utilise pack:
Code :
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.
PauseKawa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/11/2012, 09h36   #3
PauseKawa
Expert Confirmé
 
Avatar de PauseKawa
 
Homme Patrice BLANGARIN
Technicien Help Desk, maintenance, réseau, système et +
Inscription : juin 2006
Messages : 2 613
Détails du profil
Informations personnelles :
Nom : Homme Patrice BLANGARIN
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 613
Points : 3 724
Points : 3 724
La solution grid au passage:
Code :
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 :
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.
PauseKawa est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 02/11/2012, 08h14   #4
pfeuh
Membre Expert
 
Développeur en systèmes embarqués
Inscription : mars 2006
Messages : 763
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

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

Informations forums :
Inscription : mars 2006
Messages : 763
Points : 1 031
Points : 1 031
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
pfeuh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/11/2012, 17h07   #5
pfeuh
Membre Expert
 
Développeur en systèmes embarqués
Inscription : mars 2006
Messages : 763
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

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

Informations forums :
Inscription : mars 2006
Messages : 763
Points : 1 031
Points : 1 031
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 :
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
pfeuh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2012, 06h31   #6
PauseKawa
Expert Confirmé
 
Avatar de PauseKawa
 
Homme Patrice BLANGARIN
Technicien Help Desk, maintenance, réseau, système et +
Inscription : juin 2006
Messages : 2 613
Détails du profil
Informations personnelles :
Nom : Homme Patrice BLANGARIN
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 613
Points : 3 724
Points : 3 724
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.
PauseKawa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2012, 08h07   #7
pfeuh
Membre Expert
 
Développeur en systèmes embarqués
Inscription : mars 2006
Messages : 763
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

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

Informations forums :
Inscription : mars 2006
Messages : 763
Points : 1 031
Points : 1 031
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.
pfeuh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/11/2012, 14h22   #8
pfeuh
Membre Expert
 
Développeur en systèmes embarqués
Inscription : mars 2006
Messages : 763
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

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

Informations forums :
Inscription : mars 2006
Messages : 763
Points : 1 031
Points : 1 031
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 :
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()
pfeuh est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 20h27.


 
 
 
 
Partenaires

Hébergement Web