Seite 1 von 1
Problem mit horizontalem Scrollbar bei Textwidget
Verfasst: Mittwoch 11. Juni 2008, 20:25
von numerix
Ich möchte in einer Anwendung ein Text-Widget mit horizontalem und vertikalem Scrollbar. Problem:
Ich habe für das Text-Widget per width eine feste Breite gesetzt. Sobald ich den horizontalen Scrollbar ergänze, wird diese Vorgabe offenbar aber ignoriert und das Text-Widget ist nur noch so breit, wie die beiden Dreicke des Scrollbars zusammen.
Laut Doku kann man die Breite eines Scrollbars mittels dessen option width ändern. Stimmt auch, aber leider ändert man damit bei einem horizontalen Scrollbar nicht etwa die Breite des Scrollbars, sondern die Größe (in beiden Dimensionen!) der Pfeilspitzen! Sieht übel aus.
Obwohl ein Text-Widget mit zwei Scrollbars nicht so ungewöhnlich sein dürfte, habe ich auch kein Beispiel dazu gefunden. Eine kurze Notiz bei effbot.org könnte man so verstehen, dass man in Fällen wie meinem mit dem pack()-Manager nicht gut fährt und stattdessen grid() verwenden sollte.
Okay, könnte ich machen. Oder noch einen Extra-Frame einsetzen. Könnte ich auch machen.
Aber vielleicht gibt es ja doch einen Trick, um das Problem zu lösen, ohne Eingriffe am Layout der GUI vornehmen zu müssen.
Verfasst: Donnerstag 12. Juni 2008, 09:35
von wuf
Hallo pütone
Ich habe hier einmal ein Code-Schnippet für das Text-Widget mit dem Einsatz des Grid-Layout-Managers zusammengestellt. Es ist schon so, dass man mit den verschiedenen Layout-Managern herumspielen muss. Vielleicht ist dies auch der Grund, dass es von denen drei unterschiedlich Typen gibt. Ermöglicht aber eine sehr flexible Konfigurierung der GUI-Applikation. Beim herumspielen mit dem Pack-Manager kippt das Programmieren manchmal in Zauberei um Hi. Hoffe, dass ich dir hiermit ein wenig geholfen zu haben.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
Funktion: Text-Widget mit Ziehleisten in
einem positionierbaren Rahmen.
Layoutmanager: Place,Grid
Mit den Layout-Manager-Typen
muss manchmal ein bisschen herum-
gespielt werden.
Dieses Beispiel wurde auf Linux
SuSE 10.0 getestet.
"""
import Tkinter as tk
def configure_scrollbar(widget_object):
"""Konfiguriert die Ziehleiste"""
#~~ Konfiguration ist rein intuitiv!
# z.B. Van Goch, Dali, Picasso, Tcl ....
widget_object.configure(
cursor = 'hand1',
bg = 'gray',
activebackground = 'gray90',
troughcolor = 'gray50',
bd = 1,
width = 12,
highlightthickness = 0,
highlightcolor = 'red'
)
#--- Erstelle ein Tk-Hauptfenster ----
root = tk.Tk()
root.geometry('300x180')
root['bg'] = 'steelblue2'
root.title('Text-Widget mit Ziehleisten')
#~~ Konstanten
TEXT_WIDGET_FONT = ('Times','10','normal')
TEXT_WIDGET_XPOS = 50 # Pixel
TEXT_WIDGET_YPOS = 30 # Pixel
TEXT_WIDGET_WIDTH = 25 # Zeichen
TEXT_WIDGET_HEIGHT = 5 # Zeichen
#~~ Rahmen für die Aufnahme des Text-Widget
container_frame = tk.Text(root,
bd = 0,
highlightthickness = 0,
)
container_frame.place(x=TEXT_WIDGET_XPOS,y=TEXT_WIDGET_YPOS)
#~~ Text-Widget
text_plane = tk.Text(container_frame,
width = TEXT_WIDGET_WIDTH,
height = TEXT_WIDGET_HEIGHT,
relief = 'sunken',
bd = 0,
font = TEXT_WIDGET_FONT,
wrap = 'none', #'char','word'
highlightthickness = 0,
)
text_plane.grid(row=0,column=0)
#~~ Horizontale Ziehleiste
x_scrollbar = tk.Scrollbar(container_frame,
orient = 'horizontal',
command = text_plane.xview,
)
x_scrollbar.grid(row=1,column=0,sticky='we')
configure_scrollbar(x_scrollbar)
#~~ Vertikale Ziehleiste
y_scrollbar = tk.Scrollbar(container_frame,
orient = 'vertical',
command = text_plane.yview,
)
y_scrollbar.grid(row=0,column=1,sticky='ns')
configure_scrollbar(y_scrollbar)
#~~ Initialisieren der Ziehleisten
text_plane['xscrollcommand'] = x_scrollbar.set
text_plane['yscrollcommand'] = y_scrollbar.set
#~~ Setze Fokus auf das Text-Widget
text_plane.focus_set()
root.mainloop()
Gruss wuf

Verfasst: Donnerstag 12. Juni 2008, 12:50
von numerix
Da hast du dir ja - wie schön des öfteren hier - richtig viel Arbeit gemacht.
Ich hoffe, du konntest selbst (auch) davon profitieren, denn für mich wäre es jetzt nicht nötig gewesen.
Das Problem bestand ja nicht darin, dass ich es nicht realisieren konnte bzw. kann, sondern meine Hoffnung war, dass es nur irgendeines gezielten Eingriffs bedurft hätte, um das ohne die Scrollbars einwandfreie Layout vor weitergehenden Eingriffen retten zu können.
Da ich den ganzen Rest der GUI mittels pack()-Manager realisiert habe und auch alles wie gewünscht aussieht - eben bis auf den beschriebenen Effekt durch die ergänzten Scrollbars -, wollte ich nicht gerne auf das grid()-Layout umsteigen und mischen wollte ich es auch nicht.
Meine Lösung sieht jetzt so aus, dass ich einen weiteren Frame eingesetzt habe, dem ich rechts und unten die Scrollbars verpasst habe und dann das Text-Widget hineingesetzt. Das funktioniert - ebenso wie deine grid-Variante.
Verfasst: Donnerstag 12. Juni 2008, 15:46
von wuf
Hallo pütone
Freut mich, dass du eine passende Lösung gefunden hast. Für mich ist der Arbeitsaufwand für die Code-Snippets kein Problem. Alle Snippets landen bei mir in einer Ablage. Können irgendwann sicher wieder verwendet werden. Wenn ich hier etwas Code hinterlasse haben eventuell auch noch ander interessiert Forum-Mitglieder etwas davon.
Deine Lösung würde mich auch noch interessieren. Könntest du hier evt. auch noch deinen Code präsentieren, sofern du diesen nicht für ein Closed-Source-Project benötigst.
Gruss wuf

Verfasst: Donnerstag 12. Juni 2008, 16:29
von numerix
Auf das Wesentliche reduziert in etwa so:
Code: Alles auswählen
import Tkinter as tk
root = tk.Tk()
frame = tk.Frame(root)
frame.pack(side=tk.LEFT,fill=tk.Y)
editor = tk.Text(frame)
editor.pack(side=tk.TOP,fill=tk.Y,expand=True)
scroll_y = tk.Scrollbar(root,command=editor.yview)
scroll_y.pack(side=tk.LEFT,fill=tk.Y)
scroll_x = tk.Scrollbar(frame,command=editor.xview,orient=tk.HORIZONTAL)
scroll_x.pack(side=tk.BOTTOM,fill=tk.X)
editor.config(width=30,wrap="none",padx=5,pady=5,
yscrollcommand=scroll_y.set,xscrollcommand=scroll_x.set)
root.mainloop()
Verfasst: Donnerstag 12. Juni 2008, 17:10
von wuf
Hallo pütone
Besten Dank.
Super-Lösung der Aufgabe.
Wünsche die alles Gute und viel Erfolg!
Gruss wuf
