tkinter не показывает начальную таблицу, созданную на холсте - PullRequest
0 голосов
/ 08 октября 2019

Следующий код представляет собой фрагмент таблицы, изначально созданной из x cols и y строк;Я опустил код, касающийся добавления или удаления столбцов или строк. (функции onFrameConfigure и onCanvasConfigure были скопированы из ответа 8 января 16 января, опубликованного @ RDT2). Моя проблема: исходная таблица создана правильно. Но если я запрашиваю 15 столбцов и 10 строк, в корневом окне отображаются только первые 7 столбцов и первые 11 строк, что приводит к принудительной прокрутке, даже если для оставшихся строк и столбцов достаточно места. Поскольку, насколько мне известно, я нигде не ставлю никаких ограничений, я затрудняюсь объяснить и исправить это поведение.

#!/usr/bin/env python3
from tkinter import *
class Calc_Table(Frame):
    def __init__(self, root, cols, rows):
        Frame.__init__(self, root)
        self.cols = cols
        self.rows = rows
        self.configure(bg='green')
        self.grid(sticky=NSEW)
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1) 
        self.hsb = Scrollbar(orient=HORIZONTAL)
        self.hsb.grid(row = 1, column = 0, sticky = EW)
        self.vsb = Scrollbar(orient=VERTICAL)
        self.vsb.grid(row = 0, column = 1, sticky = NS)
        self.canvas = Canvas(self, xscrollcommand = self.hsb.set, yscrollcommand = self.vsb.set, bg='yellow')
        self.canvas.grid(row = 0, column = 0, sticky = NSEW)
        self.canvas.grid_rowconfigure(0, weight = 1)
        self.canvas.grid_columnconfigure(0, weight = 1)
        self.canvas.bind("<Configure>", self.onCanvasConfigure)
        self.hsb.config(command = self.canvas.xview)
        self.vsb.config(command = self.canvas.yview)
        self.table_frame = self.create_table(self.cols,self.rows)         
        self.table_frame.bind("<Configure>", self.onFrameConfigure)
        self.window = self.canvas.create_window((0, 0), window = self.table_frame, anchor=NW)
        self.canvas.config(scrollregion = self.canvas.bbox('all'))

    def onFrameConfigure(self, event):
        self.canvas.update_idletasks()
        self.canvas.configure(scrollregion=self.canvas.bbox('all'))

    def onCanvasConfigure(self, event):
        minWidth = self.table_frame.winfo_reqwidth()
        minHeight = self.table_frame.winfo_reqheight()
        if self.canvas.winfo_width() >= minWidth:
            newWidth = self.winfo_width()
            self.hsb.grid_remove()
        else:
            newWidth = minWidth
            self.hsb.grid()
        if self.canvas.winfo_height() >= minHeight:
            newHeight = self.winfo_height()
            self.vsb.grid_remove()
        else:
            newHeight = minHeight
            self.vsb.grid()
        self.canvas.itemconfig(self.window, width=newWidth, height=newHeight)

    def create_table(self, cols, rows):          # create initial table
        self.table_frame = Frame(self.canvas)
        self.table_frame.grid(column = 0, row = 0, sticky = NSEW)
        self.cols, self.rows = cols, rows
        for c in range(self.cols):
            for r in range(self.rows):
                if c == 0 and r == 0:
                    self.lbl = Label(self.table_frame, width=6, height=1, bg="white",
                                     text="? ? ?", relief=RAISED)
                    self.lbl.grid(column=c, row=r, padx=1, pady=1, sticky=NSEW)
                elif c == 0 and r != 0:
                    self.lbl = Label(self.table_frame, width=6, height=1, bg="white", 
                                     text=f"R{r}",relief=RAISED)
                    self.lbl.grid(column=c, row=r, padx=1, pady=1, sticky=NSEW)
                elif c != 0 and r == 0:
                    self.lbl = Label(self.table_frame, width=6, height=1, bg="white",
                                     text=f"C{c}",relief=RAISED)
                    self.lbl.grid(column=c, row=r, padx=1, pady=1, sticky=NSEW)
                else:
                    self.txt =Text(self.table_frame, width=6, height=1, bg="white",
                                   relief=SUNKEN)
                    self.txt.grid(column=c, row=r, padx=1, pady=1, sticky=NSEW)
        for c in range(self.cols):
            self.table_frame.grid_columnconfigure(c, weight=1)
        for r in range(self.rows):
            self.table_frame.grid_rowconfigure(r, weight=1
        for slave in self.table_frame.grid_slaves():
            slave.bind("<Button-1>", self.cmd)
        return self.table_frame              
    def cmd(self, event):
        print(event.widget.grid_info())

if __name__ == '__main__': 
    cols = int(input("How many columns? "))
    assert isinstance(int(cols), int), "integers only, please"
    rows = int(input("How many rows? "))
    assert isinstance(int(rows), int), "integers only, please"
    root = Tk()
    root.geometry("+10+10")
    root.title("Master Table")
    root.grid_columnconfigure(0, weight=1)
    root.grid_rowconfigure(0, weight=1)
    my_table = Calc_Table(root, cols, rows)
    root.mainloop()

1 Ответ

0 голосов
/ 08 октября 2019

«Проблема» в том, что вы никогда не указываете размер холста. Следовательно, это будет размер по умолчанию, независимо от содержимого.

Однако, чтобы указать размер, вам нужно знать размер создаваемого фрейма. Вы можете установить размер холста с помощью self.canvas.config() и получить требуемый размер кадра с помощью self.table_frame.winfo_reqwidth() и self.table_frame.winfo_reqheight(), но только после того, как кадр был нарисован. Вы можете отложить действие, пока все остальное не будет сделано с after_idle. Поскольку after_idle ожидает ссылку на функцию, а не вызов функции, оберните вызов в self.canvas.config() в lambda.

Собрав все это вместе, вы можете использовать

root.after_idle(lambda: self.canvas.config(width=self.table_frame.winfo_reqwidth(), height=self.table_frame.winfo_reqheight()))

в конце вашей функции __init__, чтобы изменить размер холста до того размера, который необходим кадру. Вы можете даже добавить что-то вроде min(self.table_frame.winfo_reqwidth(), 800), чтобы иметь максимальный начальный размер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...