grid, Fragen zu Layout

Fragen zu Tkinter.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Hallo zusammen

Mein betreffender Code:

Code: Alles auswählen

        entry_frame = tk.Frame(canvas)
        font = self.conf['font']
        for i, name in enumerate(self.label_names):
            label = tk.Label(entry_frame, text=name, font=font)
            label.grid(row=i, column=0, padx=10, sticky=tk.W)
            bg = ('grey', 'grey')[i & 1]
            entry = tk.Entry(entry_frame, textvariable='', width=70,
                font=font, bg=bg)
            entry.grid(row=i, column=1, ipadx=30, ipady=5, pady=2, sticky=tk.W)
            try:
                entry.insert(i, ''.join([row[i] for row in result]))
            except IndexError:
                entry.insert(i, 'IndexError')
            self.entries.append(entry)
In der Zeile ' entry.grid' habe ich 'ipadx=30', welches eigentlich den Abstand von links vom entry-Eingabefeld zum Textanfang definieren soll. Leider funktioniert das nicht, da der Textanfang immer genau links im entry-Eingabefeld beginnt.
Wie kann ich das Problem lösen?

Ich habe auch in meinen Daten überlange Texte, die dann einfach im entry-Eingabefeld abgeschnitten werden.
Eine Lösung wäre eine Scrollbar für x, was ich aber aus ergonomischen Gründen nicht möchte.
Gibt es eine Möglichkeit, den Text umbrechen zu lassen und das entry-Eingabefeld, flexibel auf die notwendige Höhe reagieren zu lassen?
Wenn ja, wie könnte hier die Lösung aussehen?
Wenn nein, gibt es noch eine andere Lösung als die Scrollbar für x?

Grüße Nobuddy
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Nobuddy

Dein beschriebenes Problem ist mir bekannt, Habe als Lösung das Entry-Widget in ein zusätzliches Frame gesetzt:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import os
try:
    #~~ For Python 2.x
    import Tkinter as tk
    import tkFont as fnt
except ImportError:
    #~~ For Python 3.x
    import tkinter as tk
    import tkinter.font as fnt

ENTRY_NAMES = [
    "Entry-1",
    "Entry-2",
    "Entry-3",
    "Entry-4",
    ]

ENTRY_BG = 'white'
ENTRY_IPADX = 5
ENTRY_IPADY = 0

class EntryFields(object):
    
    def __init__(self, app_win, entry_names=ENTRY_NAMES):
               
        entry_frame = tk.Frame(app_win)
        entry_frame.pack()
        self.entry_vars = list()
        
        for row, entry_name in enumerate(entry_names):
            entry_var = tk.StringVar()
            entry_container = tk.Frame(entry_frame, bg=ENTRY_BG,
                relief='sunken', bd=1)
            entry_container.grid(row=row, column=0)
            entry = tk.Entry(entry_container, textvariable=entry_var, width=70,
                bg=ENTRY_BG, bd=0, highlightthickness=0)
            entry.grid(row=0, column=0, padx=ENTRY_IPADX, pady=ENTRY_IPADY)
            entry_var.set(entry_name)
            self.entry_vars.append(entry_var)
            
app_win = tk.Tk()
app_win.title("Entry with ipadx & ipady")

EntryFields(app_win)

app_win.mainloop()
Gruß wuf :wink:
Take it easy Mates!
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Hallo wuf

Dein Code funktioniert! :wink:

Leider habe ich es noch nicht hinbekommen, Deinen Code bei mir so zu integrieren, daß in x der Abstand auf der linken Seite im Entry-Feld ist.
Was mir aufgefallen ist 'import tkinter.font as fnt' hat bei mir keine Auswirkung, wird auch nicht benötigt.
Ist das richtig?

Poste hier mal den Code, sollte bei Dir auch funktionieren.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

try:
    #~~ For Python 2.x
    import Tkinter as tk
    import tkFont as fnt
except ImportError:
    #~~ For Python 3.x
    import tkinter as tk
    import tkinter.font as fnt


CONFIG = {'width' : 0,
        'font': ('NimbusSansL', 14),
        'font_color': 'black',
        'back_ground' : 'orange',
        'select_mode': 'single'}



class DataGui:

    def __init__(self, default_labels, result, main_title):

        self.root = tk.Toplevel()
        self.root.title(main_title)
        self.conf = CONFIG
        self.default_labels = default_labels
        self.result = result
        xpos = 0
        ypos = 0
        self.screenx = self.root.winfo_screenwidth()
        self.screeny =  self.root.winfo_screenheight()
        self.root.geometry("%dx%d+%d+%d" % (self.screenx, self.screeny,
            xpos, ypos))

        self.frame = tk.Frame(self.root)
        self.frame.pack(side='top', fill='both', expand=True)
 
        self.root.config()
        self.label_names = self.default_labels
        self.scr_frame = self.set_scrolled_entries(self.root, self.label_names,
            self.result, self.screeny)
        self.scr_frame.pack(expand=True)

        self.button_frame = tk.Label(self.root, bg=self.conf['back_ground'])
        self.button_frame.pack(fill='x', ipady=5)

        tk.Button(self.button_frame, text="Abbrechen", font=self.conf['font'],
            fg=self.conf['font_color'], highlightthickness=0,
            command=self.root.destroy,).pack(side='right', padx=4)

        tk.Button(self.button_frame, text="Übernehmen", font=self.conf['font'],
            fg=self.conf['font_color'], highlightthickness=0,
            command='').pack(side='right', padx=4)


    def set_scrolled_entries(self, parent, label_names, result, screeny):

        self.entries = list()
 
        scroll_frame = tk.Frame(parent, bg='red')
        canvas = tk.Canvas(scroll_frame, highlightthickness=0)
        canvas.grid(row=0, column=0, sticky=tk.NSEW)
 
        yscroll = tk.Scrollbar(scroll_frame, orient=tk.VERTICAL,
            command=canvas.yview)
        yscroll.grid(row=0, column=1, sticky=tk.NS)
 
        canvas.config(yscrollcommand=yscroll.set)
        scroll_frame.grid_rowconfigure(0, weight=1)

        self.canvas = canvas
        self.bind_scroll(yscroll, self.y_scroll)

        label_frame = tk.Frame(canvas)
        for i, name in enumerate(self.label_names):
            entry_var = tk.StringVar()
            label_container = tk.Frame(label_frame,)
            label_container.grid(row=i, column=0, padx=10, pady=10, sticky=tk.NW)
            label = tk.Label(label_container, text=name, font=self.conf['font'])
            label.grid(ipady=5, sticky=tk.W)
            bg = ('grey', 'grey')[i & 1]
            entry_container = tk.Frame(label_frame,relief='sunken', bd=1)
            entry_container.grid(row=i, column=1, padx=5, pady=10,sticky=tk.NE)
            entry = tk.Entry(entry_container, textvariable=entry_var, width=70,
                font=self.conf['font'], bg=bg, bd=0, highlightthickness=0)
            entry.grid(ipadx=5, ipady=5)
            try:
                entry_var.set(''.join([row[i] for row in [result]]))
            except IndexError:
                entry_var.set('IndexError')
            self.entries.append(entry_var)

        canvas.create_window(0, 0, window=label_frame, anchor=tk.NW)
        canvas.update_idletasks()
        x, y, w, h = label_frame.bbox(tk.ALL)

        h_max = h
        if h > (self.screeny - 150):
            h_max = (self.screeny - 150)

        canvas.config(scrollregion=(x, y, w, h), width=w, height=h_max)

        return scroll_frame


    def bind_scroll(self, widget, mode):
        #~~ Windows
        widget.bind("<MouseWheel>", mode)
        #~~ Linux      
        widget.bind("<Button-4>", mode)
        widget.bind("<Button-5>", mode)


    def y_scroll(self, event):
        if event.num == 5 or event.delta < 0:
            self.canvas.yview_scroll(1, "unit")
        elif event.num == 4 or event.delta > 0:
            self.canvas.yview_scroll(-1, "unit")


    def run(self):
        self.root.mainloop()
    

if __name__ == '__main__':
    try:
        DataGui(default_labels, result, main_title).run()
    except NameError:
        result = ['TomTom', '4711', 'Hier wird erklärt, was TomTom ist.',
            'Ausführliche Beschreibung zu TomTom. Diese Beschreibung ist \
sooooooooooooooooooooo laaaaaaaaaaaaannnnnnnnnnnnnng, daß es nicht in \
eine Zeile hinein passt!', 'TomTom', '4711', 'Stück', '1', '49,90', '42,90']
        default_labels = ['Lieferant', 'Artikelnummer', 'Benennung',
            'Beschreibung', 'Hersteller', 'Herstellernummer',
            'VE', 'Inhalt', 'Vk', 'Ek']
        main_title = 'Produktdaten'
        DataGui(default_labels, result, main_title).run()
Ein Beispiel mit überlangem Text, ist auch enthalten.

Grüße Nobuddy
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Ok Nobuddy

Bevor ich mich mit deinem Skript beschäftige musst du mir erklären was die Funktion folgende Skriptzeile ist:

Code: Alles auswählen

bg = ('grey', 'grey')[i & 1]
Gruß wuf :wink:
Take it easy Mates!
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hier meine Lösung:

Code: Alles auswählen

        label_frame = tk.Frame(canvas)
        ENTRY_IPADX = 5
        ENTRY_IPADY = 2
        ENTRY_BG = 'grey'
        for i, name in enumerate(self.label_names):
            entry_var = tk.StringVar()
            label_container = tk.Frame(label_frame,)
            label_container.grid(row=i, column=0, padx=10, pady=10, sticky=tk.NW)
            label = tk.Label(label_container, text=name, font=self.conf['font'])
            label.grid(ipady=5, sticky=tk.W)
            #bg = ('grey', 'grey')[i & 1]
            bg = ENTRY_BG
            entry_container = tk.Frame(label_frame,relief='sunken', bd=1, bg=bg)
            entry_container.grid(row=i, column=1)
            entry = tk.Entry(entry_container, textvariable=entry_var, width=70,
                font=self.conf['font'], bg=bg, bd=0, highlightthickness=0)
            #entry.grid(ipadx=5, ipady=5)
            entry.grid(row=0, column=0, padx=ENTRY_IPADX, pady=ENTRY_IPADY)
Gruß wuf :wink:
Take it easy Mates!
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Nobuddy hat geschrieben:Was mir aufgefallen ist 'import tkinter.font as fnt' hat bei mir keine Auswirkung, wird auch nicht benötigt.
Ist das richtig?
Das ist richtig. Da deine in den Threads platzierten Snippets nicht immer lauffähig sind und für mich zusätzlichen Programmieraufwand bedeutet um geschilderte Probleme nachvollziehen zu können habe ich ein Standard Template-TkFramework, welches für Python2.x und Python3.x lauffähig ist. 'fnt' braucht es für deine Anwendung noch nicht. Hat aber soweit keinen Einfluss auch wenn es ungebraucht present ist.

Gruß wuf :wink:
Take it easy Mates!
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Hallo wuf

Ist noch ein Überbleibsel, was nicht mehr gebraucht wird und so auch keinen Sinn macht.
Sinn würde es so machen:

Code: Alles auswählen

bg = ('yellow', 'grey')[i & 1]
Hier wird die erste Zeile yellow, die nächste grey, dann wieder yellow usw.

Deine Lösung werde ich gleich mal testen!

Danke auch für die Info zu 'import tkinter.font as fnt' .

Grüße Nobuddy
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Hallo wuf

Deine Lösung, funktioniert jetzt auch bei mir. :D :wink:

Gibt es evtl. auch noch eine Lösung zum Zeilenumbruch innerhalb des Entry-Feldes bei überlangen Texten, oder doch Scrollbar?

Grüße Nobuddy
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Nobuddy hat geschrieben:Gibt es evtl. auch noch eine Lösung zum Zeilenumbruch innerhalb des Entry-Feldes bei überlangen Texten
Soviel ich weiss für das Entry-Widget nicht. Man könnte das Entry-Widget durch ein Text-Widget ersetzen. Rate ich dir aber nicht an da deine Tkinterkenntnisse bis ins Detail gefordert werden oder vielleicht gibt es hier in diesem Forum jemand der sich schon näher damit beschäftigt hatte und dir Lösungen präsentieren kann.

Gruß wuf :wink:
Take it easy Mates!
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Nobuddy hat geschrieben:Ist noch ein Überbleibsel, was nicht mehr gebraucht wird und so auch keinen Sinn macht.
Sinn würde es so machen:

Code: Alles auswählen

bg = ('yellow', 'grey')[i & 1]
Hier wird die erste Zeile yellow, die nächste grey, dann wieder yellow usw.
Die Lösung mittels & ist zwar einfach zu verstehen, üblich ist aber eher der Modulo-Operator:

Code: Alles auswählen

bg = ('yellow', 'grey')[i % 2]
Das Leben ist wie ein Tennisball.
BlackJack

`itertools.cycle()` ist auch ganz nützlich. Vor allem kann man danach in der Dokumentation schauen. :-)
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Hallo zusammen

Habe den Code für das betreffende Fenster mit 'Model + View' optimiert.
Hier gist.github https://gist.github.com/4134929, da der Code zum hier posten zu lange ist.

Ich habe eine Scrollbar für X integriert, welche aber noch nicht voll funktionsfähig ist.
Die X-Scrollbar ist an der richtigen Position, reagiert aber nicht auf überlange Texte.
Vielleicht könnt Ihr mir die Fehler aufzeigen, welche ich beim integrieren der X-Scrollbar gemacht habe?

Hier mal den Code-Abschnitt.

Code: Alles auswählen

    def set_scrolled_entries(self, parent, label_names, result, screeny):

        self.entry_vars = [tk.StringVar() for _ in label_names]
        self.entries = list()
 
        scroll_frame = tk.Frame(parent, bg='red')
        canvas = tk.Canvas(scroll_frame, highlightthickness=0)
        canvas.grid(row=0, column=1, sticky=tk.NSEW)
 
        xscroll = tk.Scrollbar(scroll_frame, orient=tk.HORIZONTAL,
            command=canvas.xview)
        xscroll.grid(row=1, column=1, sticky=tk.EW)
 
        yscroll = tk.Scrollbar(scroll_frame, orient=tk.VERTICAL,
            command=canvas.yview)
        yscroll.grid(row=0, column=2, sticky=tk.NS)
 
        canvas.config(xscrollcommand=xscroll.set)
        scroll_frame.grid_rowconfigure(1, weight=1)
 
        canvas.config(yscrollcommand=xscroll.set)
        scroll_frame.grid_rowconfigure(0, weight=1)

        self.canvas = canvas
        self.bind_scroll(xscroll, self.x_scroll)
        self.bind_scroll(yscroll, self.y_scroll)

        label_frame = tk.Frame(canvas)
        ENTRY_IPADX = 5 # Abstand zu Text in x
        ENTRY_IPADY = 2 # Abstand zu Text in y
        for i, (var, name) in enumerate(zip(self.entry_vars,
                self.label_names)):
            label_container = tk.Frame(label_frame,)
            label_container.grid(row=i, column=0, padx=10, pady=10,
                sticky=tk.NW)
            label = tk.Label(label_container, text=name,
                font=self.conf['font'])
            label.grid(ipady=5, sticky=tk.W)
            entry_container = tk.Frame(label_frame,relief='sunken',
                bd=1, bg=self.conf['entry_bg'])
            entry_container.grid(row=i, column=1)
            entry = tk.Entry(entry_container, textvariable=var, width=70,
                font=self.conf['font'], bg=self.conf['entry_bg'], bd=0,
                highlightthickness=0)
            entry.grid(row=0, column=0, padx=ENTRY_IPADX, pady=ENTRY_IPADY)
            try:
                var.set(''.join([row[i] for row in result]))
            except IndexError:
                var.set('IndexError')
            self.entries.append(var)

        canvas.create_window(0, 0, window=label_frame, anchor=tk.NW)
        canvas.update_idletasks()
        x, y, w, h = label_frame.bbox(tk.ALL)

        h_max = h
        if h > (self.screeny - 150):
            h_max = (self.screeny - 150)

        canvas.config(scrollregion=(x, y, w, h), width=w, height=h_max)

        return scroll_frame


    def check(self, event):
        self.controller.process(self.items)


    def run(self):
        self.root.mainloop()


    def bind_scroll(self, widget, mode):
        #~~ Windows
        widget.bind("<MouseWheel>", mode)
        #~~ Linux      
        widget.bind("<Button-4>", mode)
        widget.bind("<Button-5>", mode)


    def x_scroll(self, event):
        if event.num == 5 or event.delta < 0:
            self.canvas.xview_scroll(1, "unit")
        elif event.num == 4 or event.delta > 0:
            self.canvas.xview_scroll(-1, "unit")


    def y_scroll(self, event):
        if event.num == 5 or event.delta < 0:
            self.canvas.yview_scroll(1, "unit")
        elif event.num == 4 or event.delta > 0:
            self.canvas.yview_scroll(-1, "unit")
Grüße Nobuddy
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

@EyDo & BlackJack

Danke für eure Hinweise. Mir ist noch aufgefallen, wenn ich die Codezeile:
bg = ('yellow', 'grey')[i & 1]
in Python Code-Tags dem Forum präsentiere:

Code: Alles auswählen

bg = ('yellow', 'grey')[i & 1]
wird nach dem Punkt-Komma automatisch ein weiteres amp eingefügt. Das verstehe ich nicht ganz?

Gruß wuf :wink:
Take it easy Mates!
BlackJack

@wuf: Der doofe Syntaxhighlighter macht aus jedem '&' ein '&'. Das heisst auch aus dem ersten von '&' wenn man ihm das als Text gibt. Das '&' hat in HTML eine besondere Bedeutung, das leitet nämlich unter anderem „named entities” ein. Also zum Beispiel '&' um das '&' (engl. „ampersand”) darzustellen, oder '&copy;' für '©', oder '&auml;' für 'ä' („a-Umlaut”).
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

@BlackJack
Danke für deine präzise und gut verständliche Erklärung.

Gruß wuf :wink:
Take it easy Mates!
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Hmm, habe gerade festgestellt, daß meine X-Scrollbar zwar funktioniert, aber statt auf die horizontale Ausrichtung zu reagieren, reagiert es auf die Y-Scrollbar.
Dürfte nur noch eine Kleinigkeit sein, komme aber auch nach etlichen Versuchen nicht drauf. :?
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Wieder ein kleiner Schritt weiter.

Mein Fehler, für das synchrone Verhalten zwischen X- u. Y-Scrollbar, konnte ich lösen.
Y-Scrollbar funktioniert prima, die X-Scrollbar leider immer noch nicht.

Hier nochmals der Code-Ausschnitt, vielleicht fällt Euch was auf?

Code: Alles auswählen

    def set_scrolled_entries(self, parent, label_names, result, screeny):

        self.entry_vars = [tk.StringVar() for _ in label_names]
        self.entries = list()
 
        scroll_frame = tk.Frame(parent, bg='red')
        canvas = tk.Canvas(scroll_frame, highlightthickness=0)
        canvas.grid(row=0, column=1, sticky=tk.NSEW)
 
        xscroll = tk.Scrollbar(scroll_frame, orient=tk.HORIZONTAL,
            command=canvas.xview)
        xscroll.grid(row=1, column=1, sticky=tk.EW)
 
        yscroll = tk.Scrollbar(scroll_frame, orient=tk.VERTICAL,
            command=canvas.yview)
        yscroll.grid(row=0, column=2, sticky=tk.NS)
 
        canvas.config(xscrollcommand=xscroll.set)
        scroll_frame.grid_rowconfigure(1, weight=1)
 
        canvas.config(yscrollcommand=yscroll.set)
        scroll_frame.grid_rowconfigure(0, weight=1)

        self.canvas = canvas
        self.bind_scroll(xscroll, self.x_scroll)
        self.bind_scroll(yscroll, self.y_scroll)

        label_frame = tk.Frame(canvas)
        ENTRY_IPADX = 5 # Abstand zu Text in x
        ENTRY_IPADY = 2 # Abstand zu Text in y
        for i, (var, name) in enumerate(zip(self.entry_vars,
                self.label_names)):
            label_container = tk.Frame(label_frame,)
            label_container.grid(row=i, column=0, padx=10, pady=10,
                sticky=tk.NW)
            label = tk.Label(label_container, text=name,
                font=self.conf['font'])
            label.grid(ipady=5, sticky=tk.W)
            entry_container = tk.Frame(label_frame,relief='sunken',
                bd=1, bg=self.conf['entry_bg'])
            entry_container.grid(row=i, column=1)
            entry = tk.Entry(entry_container, textvariable=var, width=70,
                font=self.conf['font'], bg=self.conf['entry_bg'], bd=0,
                highlightthickness=0)
            entry.grid(row=0, column=0, padx=ENTRY_IPADX, pady=ENTRY_IPADY)
            try:
                var.set(''.join([row[i] for row in result]))
            except IndexError:
                var.set('IndexError')
            self.entries.append(var)

        canvas.create_window(0, 0, window=label_frame, anchor=tk.NW)
        canvas.update_idletasks()
        x, y, w, h = label_frame.bbox(tk.ALL)

        h_max = h
        if h > (self.screeny - 150):
            h_max = (self.screeny - 150)

        canvas.config(scrollregion=(x, y, w, h), width=w, height=h_max)

        return scroll_frame


    def check(self, event):
        self.controller.process(self.items)


    def run(self):
        self.root.mainloop()


    def bind_scroll(self, widget, mode):
        #~~ Windows
        widget.bind("<MouseWheel>", mode)
        #~~ Linux      
        widget.bind("<Button-4>", mode)
        widget.bind("<Button-5>", mode)


    def x_scroll(self, event):
        if event.num == 5 or event.delta < 0:
            self.canvas.xview_scroll(1, "unit")
        elif event.num == 4 or event.delta > 0:
            self.canvas.xview_scroll(-1, "unit")


    def y_scroll(self, event):
        if event.num == 5 or event.delta < 0:
            self.canvas.yview_scroll(1, "unit")
        elif event.num == 4 or event.delta > 0:
            self.canvas.yview_scroll(-1, "unit")
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Nobuddy hat geschrieben:Hier nochmals der Code-Ausschnitt, vielleicht fällt Euch was auf?
Ja. Du solltest erstmal den ganzen kopierten Code des vertikalen und des horizontalen Scrollbars zusammenführen.
Das Leben ist wie ein Tennisball.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

EyDu hat geschrieben:
Nobuddy hat geschrieben:Hier nochmals der Code-Ausschnitt, vielleicht fällt Euch was auf?
Ja. Du solltest erstmal den ganzen kopierten Code des vertikalen und des horizontalen Scrollbars zusammenführen.
Ja ich weiß, 'das Leben ist wie ein Tennisball', aber wie die Scrollbars zusammen führen?
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Ich habe den Code für die X-Scrollbar weiter nach unten, unter die for-Schleife getan, da die X-Scrollbar nicht über label und entry gehen soll, sondern nur auf das entry-Feld.

Code: Alles auswählen

    def set_scrolled_entries(self, parent, label_names, result, screeny):

        self.entry_vars = [tk.StringVar() for _ in label_names]
        self.entries = list()
 
        scroll_frame = tk.Frame(parent, bg='red')
        canvas = tk.Canvas(scroll_frame, highlightthickness=0)
        canvas.grid(row=0, column=1, sticky=tk.NSEW)
 
        yscroll = tk.Scrollbar(scroll_frame, orient=tk.VERTICAL,
            command=canvas.yview)
        yscroll.grid(row=0, column=2, sticky=tk.NS)
 
        canvas.config(yscrollcommand=yscroll.set)
        scroll_frame.grid_rowconfigure(0, weight=1)

        self.canvas = canvas
        self.bind_scroll(yscroll, self.y_scroll)

        label_frame = tk.Frame(canvas)
        ENTRY_IPADX = 5 # Abstand zu Text in x
        ENTRY_IPADY = 2 # Abstand zu Text in y
        for i, (var, name) in enumerate(zip(self.entry_vars,
                self.label_names)):
            label_container = tk.Frame(label_frame,)
            label_container.grid(row=i, column=0, padx=10, pady=10,
                sticky=tk.NW)
            label = tk.Label(label_container, text=name,
                font=self.conf['font'])
            label.grid(ipady=5, sticky=tk.W)
            entry_container = tk.Frame(label_frame,relief='sunken',
                bd=1, bg=self.conf['entry_bg'])
            entry_container.grid(row=i, column=1)
            entry = tk.Entry(entry_container, textvariable=var, width=70,
                font=self.conf['font'], bg=self.conf['entry_bg'], bd=0,
                highlightthickness=0)
            entry.grid(row=0, column=0, padx=ENTRY_IPADX, pady=ENTRY_IPADY)
            try:
                var.set(''.join([row[i] for row in result]))
            except IndexError:
                var.set('IndexError')
            self.entries.append(var)
 
        xscroll = tk.Scrollbar(scroll_frame, orient=tk.HORIZONTAL,
            command=canvas.xview)
        xscroll.grid(row=1, column=1, sticky=tk.EW)
 
        canvas.config(xscrollcommand=xscroll.set)
        scroll_frame.grid_rowconfigure(1, weight=1)
        self.bind_scroll(xscroll, self.x_scroll)

        canvas.create_window(0, 0, window=label_frame, anchor=tk.NW)
        canvas.update_idletasks()
        x, y, w, h = label_frame.bbox(tk.ALL)

        h_max = h
        if h > (self.screeny - 150):
            h_max = (self.screeny - 150)

        canvas.config(scrollregion=(x, y, w, h), width=w, height=h_max)

        return scroll_frame
Antworten