Le code ci-dessous produit un exemple laid mais fonctionnel de l'utilisation d'une barre de défilement dans un widget de texte et entraîne quelques questions. Remarque: cela se fait en utilisant Python 3 sur une boîte Windows.
La barre de défilement qui apparaît est attachée au cadre et bien qu'elle fasse défiler le contenu de la zone de texte, je préférerais qu'elle soit attachée au widget de texte lui-même. Je n'ai pas pu obtenir que cela se produise.
Il y a un certain nombre de références à un module Tkinter appelé "scrolledtext" qui est censé être un bien meilleur mécanisme pour ajouter des barres de défilement aux zones de texte mais, je n'ai trouvé aucun exemple de comment l'importer et l'appeler que je suis capable de se mettre au travail (probablement besoin d'un exemple).
frame1 = tk.Frame(win,width=80, height=80,bg = '#808000')
frame1.pack(fill='both', expand='yes')
scrollbar = Scrollbar(frame1)
scrollbar.pack(side=RIGHT, fill=Y)
editArea = Text(frame1, width=10, height=10, wrap=Word, yscrollcommand=scrollbar.set)
editArea.pack()
scrollbar.config(command=editArea.yview)
editArea.place(x=10,y=30)
Vous aviez raison, vous pouvez utiliser le widget ScrolledText
de tkinter.scrolledtext
module, comme ceci:
import tkinter as tk
import tkinter.scrolledtext as tkst
win = tk.Tk()
frame1 = tk.Frame(
master = win,
bg = '#808000'
)
frame1.pack(fill='both', expand='yes')
editArea = tkst.ScrolledText(
master = frame1,
wrap = tk.Word,
width = 20,
height = 10
)
# Don't use widget.place(), use pack or grid instead, since
# They behave better on scaling the window -- and you don't
# have to calculate it manually!
editArea.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
# Adding some text, to see if scroll is working as we expect it
editArea.insert(tk.INSERT,
"""\
Integer posuere erat a ante venenatis dapibus.
Posuere velit aliquet.
Aenean eu leo quam. Pellentesque ornare sem.
Lacinia quam venenatis vestibulum.
Nulla vitae elit libero, a pharetra augue.
Cum sociis natoque penatibus et magnis dis.
Parturient montes, nascetur ridiculus mus.
""")
win.mainloop()
Et voilà:
Bien que l'utilisation du widget ScrolledText puisse vous faire économiser quelques lignes de code, il ne fait rien que vous ne puissiez pas faire vous-même. Le faire vous-même aidera à éliminer une partie du mystère.
Vous faites en fait tout ce qui est presque correct. L'erreur que vous faites est que votre widget de texte doit remplir complètement son conteneur plutôt que d'en être une infime partie.
La façon standard de procéder est la suivante:
container = tk.Frame(...)
text = tk.Text(container, ...)
scrollbar = tk.Scrollbar(container, ...)
scrollbar.pack(side="right", fill="y")
text.pack(side="left", fill="both", expand=True)
C'est tout ce qu'on peut en dire. Maintenant, peu importe la taille de votre conteneur en raison du redimensionnement des fenêtres, etc., la barre de défilement apparaîtra toujours attachée au widget de texte. Vous traitez ensuite ce groupe entier de conteneur, widget texte et barre de défilement comme un widget unique lorsque vous l'ajoutez à l'ensemble de votre interface graphique.
Notez que vous pouvez également utiliser la grille ici. Le pack est plus facile si vous ne disposez que d'une barre de défilement verticale. Si vous avez des barres de défilement horizontales et verticales, la grille a un peu plus de sens.
Pour compléter l'illusion, vous pouvez définir la largeur de bordure du widget de texte à zéro, et définir la largeur de bordure du cadre contenant à 1 avec un relief de creux, et la barre de défilement semblera être "dans" le widget de texte.
Voici un exemple de travail complet qui ressemble plus ou moins à votre exemple:
import Tkinter as tk
win = tk.Tk()
win.configure(background="#808000")
frame1 = tk.Frame(win,width=80, height=80,bg = '#ffffff',
borderwidth=1, relief="sunken")
scrollbar = tk.Scrollbar(frame1)
editArea = tk.Text(frame1, width=10, height=10, wrap="Word",
yscrollcommand=scrollbar.set,
borderwidth=0, highlightthickness=0)
scrollbar.config(command=editArea.yview)
scrollbar.pack(side="right", fill="y")
editArea.pack(side="left", fill="both", expand=True)
frame1.place(x=10,y=30)
win.mainloop()
Personnellement, je ne recommande pas de faire des importations globales et je ne recommande pas d'utiliser place, mais je voulais garder cela aussi proche que possible de votre original.