Habe hier einen funktionierenden Code, der das Problem erkennen lässt.
Wenn Du ein paar mal auf den Button "+Data" betätigst und dann das Gleiche mit dem "-Data" Button machst, kannst Du es erkennen, was ich meine.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x
import tkinter as tk
from datetime import date, timedelta
now = date.today()
heute = now.strftime('%Y.%m.%d')
class BuildingWindow(object):
"""
Bausteine zur Fenster-Erstellung.
"""
def __init__(self, tk_status, document, label, data):
# TK
try:
self.tk_status = tk_status
except AttributeError:
self.tk_status = 'tk'
tk_check = {'tk' : tk.Tk, 'top' : tk.Toplevel}
self.my_win = tk_check[self.tk_status]()
self.my_win.protocol("WM_DELETE_WINDOW", self.close)
self.label = label
self.data = data
self.table_width2column = dict([(i, len(x) + 10)
for i, x in enumerate(data[0])])
self.color = 'yellow'
# Ermittle die Größe des Bildschirmes
self.screenx = self.my_win.winfo_screenwidth()
self.screeny = self.my_win.winfo_screenheight()
# Basis-Fenster
self.window = tk.Frame(
self.my_win,
bg=self.color
)
self.window.grid(
row=0,
column=0,
sticky=tk.NSEW
)
self.window.grid_rowconfigure(0, weight=1)
self.window.grid_columnconfigure(0, weight=1)
# Build formular
def build_formulars_view(self):
"""
Erstellung Formular-Fenster.
"""
# Startwerte für Gesamtfenster.
self.y_window = 17 # title
self.x_window = 0
self.x_window_list = list()
# Erstelle scrollbar für y und x.
self.table_work = False
self.canvas = tk.Canvas(
self.window,
)
self.canvas.grid(
row=0,
column=0,
sticky=tk.NSEW
)
self.x_yscroll = 0
self.y_xscroll = 0
if len(self.data) > 0:
self.table_work = True
yscrollbar = tk.Scrollbar(
self.window,
orient=tk.VERTICAL,
activebackground='lightsteelblue',
troughcolor='yellow'
)
yscrollbar.grid(
row=0,
column=1,
sticky=tk.NS
)
xscrollbar = tk.Scrollbar(
self.window,
orient=tk.HORIZONTAL,
activebackground='lightsteelblue',
troughcolor='yellow'
)
xscrollbar.grid(
row=1,
column=0,
sticky=tk.EW
)
# Festlegung der Scrollregion.
self.canvas.config(
scrollregion=(0, 0, 0, 0),
xscrollcommand=xscrollbar.set,
yscrollcommand=yscrollbar.set)
# Konfiguration Scrollbar in y und x.
yscrollbar.config(command=self.canvas.yview)
xscrollbar.config(command=self.canvas.xview)
self.x_yscroll = yscrollbar.winfo_reqwidth()
self.y_xscroll = xscrollbar.winfo_reqheight()
self.y_window += self.y_xscroll
# Buttons erstellen
self.y_button = 0
self.load_buttons()
self.y_window += self.y_button
# Erstelle Benennungsspalte.
self.y_label = 0
self.set_labels()
# Erstelle Tabelle mit Daten.
self.y_table = 0
self.set_entrys()
self.x_window += max(self.x_window_list)
print('###################################')
print('self.y_window', self.y_window)
print('self.x_window', self.x_window)
print('self.y_button', self.y_button)
print('self.y_label', self.y_label)
print('self.y_table', self.y_table)
print('###################################')
print(self.canvas.bbox(tk.ALL))
# Layoutsteuerung für Canvas
(self.x, self.y, self.x_table_scroll, self.y_table_scroll
) = self.set_up_dimensions()
print(self.x, self.y, self.x_table_scroll, self.y_table_scroll)
print('###################################')
# Konfiguration Canvas mit aktuellen Werten für:
# Scrollregion, Fensterbreite und Fensterhöhe.
self.canvas.config(
scrollregion=(self.canvas.bbox(tk.ALL)),
width=self.x_table_scroll,
height=self.y_table_scroll
)
# Aktualisierung Fenster
self.screen_update()
def add_data(self):
"""
Füge einen Datensatz in die Tabelle ein.
"""
new_row = self.data[-1].copy()
new_pos = str(int(new_row[0]) + 1)
position = '{}{}'.format((3 - len(new_pos)) * '0', new_pos)
new_row[0] = position
self.data.append(new_row)
self.build_formulars_view()
return
def remove_data(self):
"""
Füge einen Datensatz in die Tabelle ein.
"""
del self.data[-1]
self.build_formulars_view()
return
def screen_update(self):
"""
Aktualisierung, X- und Y-Koordinaten der GUI.
"""
# Zentriere das Fenster auf dem Bildschirm
x, y, hdw, hdh = self.center_window()
self.my_win.geometry('{}x{}+{}+{}'.format(x, y, hdw, hdh))
self.my_win.update()
def center_window(self):
"""
Zentrierung von Fenster auf Bildschirm,
wenn Fenster kleiner als Bildschirm.
"""
# Berechne die halbe Differenz zwischen Bildschirm und Fenster
half_diff_width = 0
if ((self.screenx - self.x) / 2) > 0:
half_diff_width = round((self.screenx - self.x) / 2)
half_diff_hight = 0
if ((self.screeny - self.y) / 2) > 0:
half_diff_hight = round((self.screeny - self.y) / 2)
# Werte für das Zentrieren das Fensters auf dem Bildschirm
return self.x, self.y, half_diff_width, half_diff_hight
def set_up_dimensions(self):
"""
Überprüfung und Aktualisierung der Fenster-Breite / Höhe.
"""
# Fensterbreite in X
self.width_to_screen()
# Fensterhöhe in Y
self.heigth_to_screen()
# Scrollbreite in X
self.scroll_to_x()
# Scrollhöhe in Y
self.scroll_to_y()
return self.x, self.y, self.x_table_scroll, self.y_table_scroll
def width_to_screen(self):
"""
Ermittlung der Fensterbreite, unter Beachtung der Displaybreite.
"""
self.x = self.x_window + self.x_yscroll
if self.x_window > self.screenx:
self.x = self.screenx + self.x_yscroll
return
def heigth_to_screen(self):
"""
Ermittlung der Fensterhöhe, unter Beachtung der Displayhöhe.
"""
self.y = self.y_window + self.y_table
if self.y > self.screeny:
self.y = self.screeny
return
def scroll_to_x(self):
"""
Ermittlung der maximalen Scrollbreite für yscroll,
unter Beachtung der Displaybreite.
"""
self.x_table_scroll = self.x_window + self.x_yscroll
if not self.table_work:
# Leere Tabelle
self.x_table_scroll = 0
elif self.x_table_scroll > self.screenx:
# Scrollbreite größer als Displaybreite
self.x_table_scroll = self.screenx - (2*self.x_yscroll)
return
def scroll_to_y(self):
"""
Ermittlung der maximalen Scrollhöhe für yscroll,
unter Beachtung der Displayhöhe.
"""
self.y_table_scroll = self.y_table
if self.screeny < self.y:
# Scrollhöhe größer als Displayhöhe
self.y_table_scroll = self.screeny - self.y_window
return
def load_buttons(self):
"""
Erstellung Buttons.
"""
self.buttons = {
0 : ('+ data', lambda: self.add_data()),
1 : ('- data', lambda: self.remove_data()),
3 : ('Schließen', lambda: self.close()),
}
self.button_frame = tk.Label(
self.window,
bg=self.color
)
self.button_frame.grid(
row=2,
column=0,
sticky=tk.E
)
button_width = max([len(self.buttons[i])
for i in self.buttons]) + 5
x_sum = 0
for i in sorted(self.buttons):
name, command = self.buttons[i]
self.button_widget = tk.Button(
self.button_frame,
width=button_width,
text=name.upper(),
command=command
)
self.button_widget.grid(
row=0,
column=i + 1
)
x_sum += self.button_widget.winfo_reqwidth()
self.y_button += self.button_widget.winfo_reqheight()
self.x_window_list.append(x_sum)
return
def set_labels(self):
"""
Erstellung Benennungsspalte
"""
ypos = 0
xpos = 0
for i, name in enumerate(self.label):
width = self.table_width2column[i]
label = tk.Label(
self.canvas,
width=width,
text=name.upper(),
bg='lightgreen',
bd=1,
highlightthickness=1,
anchor=tk.NW
)
label.grid(
row=0,
column=i,
)
self.canvas.create_window(
xpos,
label.winfo_reqheight(),
window=label,
anchor=tk.NW
)
xpos += label.winfo_reqwidth()
self.x_window_list.append(xpos)
self.y_label += label.winfo_reqheight()
return
def set_entrys(self):
"""
Erstellung Tabellenspalte
"""
row_start = 0
if self.y_label > 0:
#self.y_table += self.y_label
row_start = 1
self.y_table += (2*self.y_label)
for i, row in enumerate(self.data):
xpos = 0
for s, width in self.table_width2column.items():
self.var = tk.StringVar(value=row[s].upper())
self.entry = tk.Entry(
self.canvas,
text=self.var,
width=width,
bd=1,
highlightthickness=1
)
self.entry.grid(
row=i + row_start,
column=s,
)
self.canvas.create_window(
xpos,
self.y_table,
window=self.entry,
anchor=tk.NW
)
xpos += self.entry.winfo_reqwidth()
self.y_table += self.entry.winfo_reqheight()
self.x_window_list.append(xpos)
self.y_table -= self.y_label
return
def close(self):
"""
Beendigung ohne Datenübernahme.
"""
self.take_end = False
self.my_win.quit()
self.my_win.destroy()
return
def run(self, title):
self.my_win.title(title)
self.build_formulars_view()
self.my_win.mainloop()
def main(document):
tk_status = 'tk'
client = 'kunde'
label = ['position', 'artikel', 'benennung', 'hersteller',
'herstellernummer', 've', 'inhalt', 'vk', 'mwst']
data = [['001', '123456789', 'pppppppppppppppppppppppppppppppppppppppppppppppprodukt 123456789, din a4, weiß, 80g',
'hersteller', 'herstellernummer', 'stück', '1', '3.25', '0.19']]
title = '{}: {}'.format(document.upper(), client.upper())
BuildingWindow(tk_status, document, label, data).run(title)
if __name__ == '__main__':
document = 'test'
main(document)