Разделите классы графического интерфейса Tkinter на более значимые способы.

Я пытаюсь сделать следующий код максимально осмысленным, используя наследование. Цель - учиться. Класс App — самый суперкласс. И класс Tabs унаследовал его. Могу ли я сделать следующий код более осмысленным и разбить его на более качественные классы? Вместо того, чтобы создавать тетрадь = self.notebook для всех методов класса Tabs, я не могу инициализировать его в методе в этом класса Tab. Когда это было сделано, ноутбук был неузнаваем. Мне нужно, чтобы цвет фона всех вкладок был одинаковым. Следовательно, если я могу упомянуть об этом в методе инициализации класса Tabs и преобразовать его другие методы (о,..., визуализировать) в дочерние классы класса Tabs, будет ли это хорошим предложением? Пожалуйста, помогите

import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
from tkinter.filedialog import askopenfile
from tkinter.font import Font


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        # intializing the window
        
        self.title("Data Visualization")

        # configuring size of the window
        self.geometry('800x650')
        
        # this removes the maximize button
        self.resizable(0,0)

        # Styling the tabs
        s = ttk.Style()
        s.theme_create('pastel', settings={
            ".": {
                "configure": {
                    "background": '#ffffff', # All except tabs
                    "font": 'red'
                }
            },
            "TNotebook": {
                "configure": {
                    "background":'#848a98', # Your margin color
                    "tabmargins": [5, 5, 4, 4], # margins: left, top, right, separator
                }
            },
            "TNotebook.Tab": {
                "configure": {
                    "background": '#d9ffcc', # tab color when not selected
                    "padding": [10, 2], # [space between text and horizontal tab-button border, space between text and vertical tab_button border]
                    "font":"white"
                },
                "map": {
                    "background": [("selected", '#ccffff')], # Tab color when selected
                    "expand": [("selected", [1, 1, 1, 0])] # text margins
                }
            }
        })

        s.theme_use('pastel')
        #s.theme_use('default')
        s.configure('TNotebook.Tab', font=('URW Gothic L','13','bold'))
        #s.map("TNotebook", background= [("selected", "#ffffff")])
   

         #Create Tab Control
        
        self.notebook = ttk.Notebook(self)
        

    
class Tabs(App):
    
    def __init__(self):
        super().__init__()
    
    def about(self):
        
        my_font = Font(
            family = 'Arial',
            size = 15,
            weight = 'bold',
            slant = 'roman',
            underline = 0,
            overstrike = 0
        )
    
        my_font2 = Font(
            family = 'Arial',
            size = 11,
            #weight = 'bold',
            slant = 'roman',
            underline = 0,
            overstrike = 0
        )

        notebook = self.notebook
        f1 = tk.Frame(notebook)#,background="#FFFAF0")
        
                
        #logo
        logo = Image.open('airport.jpg')
        #Resize the Image using resize method
        resized_image= logo.resize((600,300), Image.ANTIALIAS)
        logo = ImageTk.PhotoImage(resized_image)
        logo_label = ttk.Label(f1,image=logo,relief="raised")
        logo_label.image = logo
        #logo_label.grid(column=3, row=0)
        logo_label.place(relx=0.12,rely=0.1) # using place
        notebook.add(f1, text="About" )
 
        
        # Tab1
        ttk.Label(f1, text="Airports, Airport-frequencies and Runways analysis", font=my_font).place(relx=0.2,rely=0.03)

        #text box
        
        text_box = tk.Text(f1, height =10,font=my_font2)
        text_box.insert(1.0,"""This application allows you to analyze Airports, Airport-frequencies and Runways of Europe.
        
        • Tab "Load and Save Actions" is to load the initial data set (which consists of three CSV files) and translate it into a suitable format. \n\n• Tab "Preprocess" is to clean and prepare the initial data set, managing inconsistences, \nerrors, missing values and any specific changes required. \n\n• Tab "Visualize" is to use the prepared data set to generate output and visualisations.""" )
        text_box.tag_configure("center", justify="center")
        text_box.tag_add("center", 1.0, "end")
        text_box.place(relx=0.1, rely=0.65)
        text_box.config(highlightthickness = 2, borderwidth=0,background='#FFFAFA')
        notebook.pack(expand=1, fill="both")
        
    def load_save(self):
        notebook = self.notebook
        f2 = tk.Frame(notebook,background="#ffffff")
        notebook.add(f2, text="Load and Save Actions" )
        
        
    def preprocess(self):
        notebook = self.notebook
        f3 = tk.Frame(notebook,background="#ffffff")
        notebook.add(f3, text="Preprocess" )
        
        
    def visualize(self):
        notebook = self.notebook
        f4 = tk.Frame(notebook,background="#ffffff")
        notebook.add(f4, text="Visualize" )
    

if __name__ == "__main__":
    

    tabs=Tabs()
    tabs.about()
    tabs.load_save()
    tabs.preprocess()
    tabs.visualize()
    tabs.mainloop()

Гм... да, вы действительно можете реорганизовать свой код. Какой конкретно вопрос? Это кажется немного основанным на мнении для SO. Если вы просите нас исправить форматирование вашего кода, возможно, это будет лучший вопрос для Проверка кода SE. Обязательно сначала прочитайте их центр помощи, в частности, что там за по теме.

Sylvester Kruin 22.04.2022 20:53
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
0
1
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В вашем примере Tabs должен наследовать нет от App. Наследование — это отношение это. Если Tabs наследуется от App, это означает, что TabsэтоApp. Это означает, что теперь у вас есть две Apps: оригинальная плюс специализированная версия.

Это особенно проблематично с tkinter. Tkinter спроектирован так, чтобы иметь ровно один экземпляр Tk, но у вас есть один для App (начиная с AppэтоTk) плюс по одному для каждого экземпляра Tab. Это приведет к неинтуитивному и нежелательному поведению.

Наследование не для обмена данными между объектами. Если Tabs требуется доступ к данным или функциям в App, он должен сделать это, вызвав функции или получив доступ к данным из самого экземпляра App.

Лучшей структурой является создание пользовательского класса для вкладки, а затем создание экземпляров этого класса, а не создание функций, создающих вкладку.

Вот пример, где экземпляр app передается на каждую вкладку. Затем вкладка может использовать self.app для вызова функций или доступа к переменным в App. Класс Tab создаст фрейм в app.notebook с некоторыми общими параметрами.

Делая каждую вкладку классом, вы получаете удобный способ инкапсулировать функции и данные, характерные для каждой вкладки.

import tkinter as tk
from tkinter import ttk

class App(tk.Tk):
    def __init__(self):
        super().__init__()

        ...
        self.notebook = ttk.Notebook(self)
        self.notebook.pack(fill="both", expand=True)

        self.about_tab = AboutTab(app=self)
        self.load_save = LoadSaveTab(app=self)

class Tab(tk.Frame):
    def __init__(self, app, label):
        # given an app, make this a child of app.notebook
        self.app = app
        super().__init__(app.notebook, background="#FFFAF0")
        self.app.notebook.add(self, text=label)

class AboutTab(Tab):
    def __init__(self, app):
        super().__init__(app, "About")

        label = tk.Label(self, text="This is the 'About' tab")
        label.pack(fill="both")
        ...

class LoadSaveTab(Tab):
    def __init__(self, app):
        super().__init__(app, "Load and Save")

        label = tk.Label(self, text="This is the 'Load and Save' tab")
        label.pack(fill="both")
        ...

if __name__ == "__main__":
    app = App()
    app.mainloop()

Понял, Брайан... ясно... Я уберу унаследованное от приложения...

user3789200 22.04.2022 22:58

Спасибо .... :)

user3789200 23.04.2022 09:16

Другие вопросы по теме