Создание большого количества кнопок в Tkinter - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть программа tkinter, которая берет данные из базы данных SQL и сохраняет их в двумерном массиве, а затем отображает эти данные в виде таблицы кнопок.

Соответствующие вопросы: это , это , и это

Хотя вышеупомянутые вопросы касаются главным образом холстов, моя проблема с производительностью касается меток / кнопок и начальных отображение их. Массив может содержать от 600 до 800 ячеек данных, и когда я пытаюсь отобразить их в первый раз, они отображаются по одному, а не все сразу.

Пример кода

import tkinter as tk
from random import randint


class Main(tk.Frame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)

        self.canvas = tk.Canvas(self)
        self.interior = tk.Frame(self)
        self.id = self.canvas.create_window(0, 0, window=self.interior, anchor="nw")
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.hsb = tk.Scrollbar(self, orient="horizontal", command=self.canvas.xview)
        self.canvas.config(yscrollcommand=self.vsb.set)
        self.canvas.config(xscrollcommand=self.hsb.set)
        self.interior.bind("<Configure>", lambda event: self.on_config())

        self.rows, self.columns = 15, 51
        self.data = [[randint(25, 99) for _ in range(self.columns)] for _ in range(self.rows)]
        self.btns = [[None for _ in range(self.columns)] for _ in range(self.rows)]

    def grid(self, **kwargs):
        super(tk.Frame, self).grid(**kwargs)
        self.canvas.grid(row=0, column=0, sticky='nesw')
        self.vsb.grid(row=0, column=1, sticky='nesw')
        self.hsb.grid(row=1, column=0, sticky='nesw')
        self.display_data(True)

    def display_data(self, is_first=False):
        if not is_first:
            self.modify_cells()
            return
        for row in range(self.rows):
            for column in range(self.columns):
                cell = self.data[row][column]
                btn = tk.Button(self.interior, text=cell, fg='white', bg='red', relief='flat',
                                command=lambda column_index=column:
                                self.sort(column_index))
                self.btns[row][column] = btn
                btn.grid(row=row, column=column, sticky='nesw')

    def sort(self, column_index):
        self.data.sort(key=lambda x: x[column_index])
        self.display_data()

    def modify_cells(self):
        for row in range(self.rows):
            for column in range(self.columns):
                btn = self.btns[row][column]
                btn.config(text=self.data[row][column])

    def on_config(self):
        self.update_idletasks()
        self.interior.update_idletasks()
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))                

win = tk.Tk()
ui = Main(win)
ui.grid(sticky='nesw')
win.mainloop()

Сортировка столбца (который изменяет текст на кнопках) достаточно быстра, но проблема заключается в первоначальном создании и отображении кнопок.

Следует также отметить что я знаю о виджете Treeview (который решает эту проблему), но я бы предпочел сохранить то, что у меня есть сейчас, из соображений эстетики c, если это вообще возможно.

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