Mit einer Scrollbar zwei Textboxen gleichzeitig scrollen

Fragen zu Tkinter.
Antworten
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Hallo zusammen,

ich habe zwei Textboxen der gleichen Höhe direkt nebeneinander. In das Linke soll der Benutzer Text eintragen können. Dieser Text wird zeilenweise analysiert und das Ergebnis in der rechten Textbox ausgegeben.
Falls der Benutzer aber viel Text eingibt oder das Fenster sehr klein zieht, dann reicht der Platz im Eingabetextfeld nicht aus und es muss gescrollt werden. Die Auswertung in der zweiten Textbox muss aber dann simultan mitgescrollt werden, damit eingegebener Text und die Auswertung weiterhin auf der gleichen Höhe bleiben.

Ich habe testweise zwei Textfelder mit einer Scrollbar erstellt, aber leider wird dann nur das linke Eingabetextfeld gescrollt. Kann mir jemand sagen was ich ändern muss, dass beide Textfelder über die eine Scrollbar gescrollt werden? Ich konnte leider keine funktionierende Lösung finden...

Code: Alles auswählen

import tkinter as tk

FIELD_HEIGHT = 5

class MainWindow:
    def __init__(self, master):
        self.master = master

        self.input_field = tk.Text(self.master, height=FIELD_HEIGHT, width=20)
        self.input_field.grid(row=0, column=0, sticky='nws')

        self.output_field = tk.Text(self.master, height=FIELD_HEIGHT, width=10)
        self.output_field.grid(row=0, column=1, sticky='nes')

        self.scrollbar = tk.Scrollbar(self.master)
        self.scrollbar.config(command=self.input_field.yview)
        self.scrollbar.grid(row=0, column=0, sticky='nes')

        self.master.grid()


def main():
    root = tk.Tk()
    app = MainWindow(root)
    root.mainloop()

if __name__ == '__main__':
    main()
Muss ich hier irgendwie mit bind ein Event verwenden? Aber wie spreche ich dann die Textboxen an?

Schon einmal vielen Danke!
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst eine Funktion schrieben, die einfach beide yview Attribute setzt. Und die dem scrollbar mitgeben.
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

So einfach finde das leider gar nicht... :roll:

Eine Funktion zu definieren, die beim Scrollen aufgerufen wird, haben ich jetzt auf zwei Arten geschafft.
Als Funktion:

Code: Alles auswählen

        self.scrollbar.configure(command=self.scrolling())
        
    def scrolling(self):
        pass
und als Event:

Code: Alles auswählen

        self.scrollbar.bind("<Configure>", self.scrolling)
        
    def scrolling(self, event):
        pass
Aber was muss in scrolling() drin stehen? Schreibe ich da so etwas wie

Code: Alles auswählen

        self.scrollbar.config(command=self.input_field.yview)
        self.scrollbar.config(command=self.output_field.yview)
wird die ersten Zeile von der zweiten überschrieben und es scrollt wieder nur eine Textbox.

Wie genau kann ich denn beide yview Attribute so setzen, dass beide gültig sind?
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Eine Funktion zu schreiben, sollte einfach sein, wenn man sich schon mit Klassen beschäftigt.
Zusätzlich muß natürlich noch die Rückrichtung implementiert werden, dass wenn man sich im Textfeld bewegt, der Scrollbar angepasst wird.

Code: Alles auswählen

import tkinter as tk

FIELD_HEIGHT = 5

class MainWindow:
    def __init__(self, master):
        self.master = master

        self.input_field = tk.Text(self.master, height=FIELD_HEIGHT, width=20,
            yscrollcommand = self.scrollbar_set)
        self.input_field.grid(row=0, column=0, sticky='nws')

        self.output_field = tk.Text(self.master, height=FIELD_HEIGHT, width=10,
            yscrollcommand = self.scrollbar_set)
        self.output_field.grid(row=0, column=1, sticky='nes')

        self.scrollbar = tk.Scrollbar(self.master, command=self.fields_yview)
        self.scrollbar.grid(row=0, column=2, sticky='nes')

    def scrollbar_set(self, first, last):
        self.scrollbar.set(first, last)
        self.input_field.yview("moveto", first)
        self.output_field.yview("moveto", first)

    def fields_yview(self, cmd, position):
        self.input_field.yview(cmd, position)
        self.output_field.yview(cmd, position)


def main():
    root = tk.Tk()
    app = MainWindow(root)
    root.mainloop()

if __name__ == '__main__':
    main()
Antworten