1
\$\begingroup\$

I'm trying to make the following code meaningful as much as possible, using inheritance. The purpose is for learning. The App class is the most super class. And the Tabs class has inherited it. Can I make the following code more meaningful and break it for more better classes? Instead of creating notebook = self.notebook for all the Tabs class methods, can't I initialize it in the Tab class's init method. When it is done notebook was non recognizable. I need all the tabs background color to be same. Hence, if I can mention it in the Tabs class's init method and convert its other methods(about, ..., visualize) into child classes of Tabs class, will it be a good suggestion? kindly help

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()
Reinderien
70.9k5 gold badges76 silver badges256 bronze badges
asked Apr 22, 2022 at 19:13
\$\endgroup\$
1
  • \$\begingroup\$ Please edit your question so that the title describes the purpose of the code, rather than its mechanism. We really need to understand the motivational context to give good reviews. Thanks! \$\endgroup\$ Commented Apr 22, 2022 at 21:17

1 Answer 1

2
\$\begingroup\$

meaningful as much as possible, using inheritance

Inheritance basically has no place here. Eventually, if your tab sections are larger and share more common elements, then perhaps having a Tab superclass would make sense, but it should absolutely not inherit from App.

Can I make the following code more meaningful and break it for more better classes?

I have no idea what that means, but you'll either want one single class, or perhaps eventually one class per tab.

Otherwise:

Don't inherit from Tk; instantiate it (has-a, not is-a).

In a few places you've passed 0 where you should pass False. A mature IDE like PyCharm, or probably a type-checking tool like mypy, will tell you this. This includes the call to resizable.

Long, constant literals such as your style dictionary may be better-suited to values in effectively static scope.

Methods such as about should be

  • called by your constructor, not by the instantiating code;
  • named perhaps _make_preprocess or _setup_preprocess - not preprocess - since this isn't doing the preprocessing
  • marked private via leading underscore; and
  • type-hinted as returning None.

You know about tk's ability to process named colours like white, since you've used that - so why would you also be passing #ffffff? Prefer the former.

Some of your comments, such as # tab color when not selected, are fine since they're describing something non-obvious. Most others need to be deleted, particularly those like:

 logo_label.place() # using place

f2 is a bad name for at least two reasons. First, it's meaningless and should include the word "frame". Second: this method should work and make sense regardless of whether the frame is actually the second frame. The notebook does not need an index for its add call. So just call it frame.

Similarly, don't say my_font; this is actually the label_font.

I do not have your airport.jpg so for illustrative purposes I have substituted my own.

Suggested

import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
from tkinter.font import Font
class App:
 TAB_SETTINGS = {
 '.': {
 'configure': {
 'background': 'white', # 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
 }
 }
 }
 def __init__(self) -> None:
 root = self.root = tk.Tk()
 root.title('Data Visualization')
 root.geometry('800x650')
 # this removes the maximize button
 root.resizable(False, False)
 s = ttk.Style()
 s.theme_create('pastel', settings=self.TAB_SETTINGS)
 s.theme_use('pastel')
 s.configure('TNotebook.Tab', font=('URW Gothic L', '13', 'bold'))
 self.notebook = ttk.Notebook(root)
 self._make_about()
 self._make_load_save()
 self._make_preprocess()
 self._make_visualise()
 self.run = root.mainloop
 def _make_about(self) -> None:
 label_font = Font(
 family='Arial',
 size=15,
 weight='bold',
 slant='roman',
 underline=False,
 overstrike=False,
 )
 textbox_font = Font(
 family='Arial',
 size=11,
 slant='roman',
 underline=False,
 overstrike=False,
 )
 frame = tk.Frame(self.notebook)
 logo = Image.open('airplane.png')
 resized_image = logo.resize((600, 300), Image.ANTIALIAS)
 logo = ImageTk.PhotoImage(resized_image)
 logo_label = ttk.Label(frame, image=logo, relief='raised')
 logo_label.image = logo
 logo_label.place(relx=0.12, rely=0.1)
 self.notebook.add(frame, text='About')
 ttk.Label(
 frame,
 text='Airports, Airport-frequencies and Runways analysis',
 font=label_font,
 ).place(relx=0.2, rely=0.03)
 text_box = tk.Text(frame, height=10, font=textbox_font)
 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.
• Tab "Preprocess" is to clean and prepare the initial data set, managing inconsistences,
errors, missing values and any specific changes required.
• 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')
 self.notebook.pack(expand=1, fill='both')
 def _make_load_save(self) -> None:
 frame = tk.Frame(self.notebook, background='white')
 self.notebook.add(frame, text='Load and Save Actions')
 def _make_preprocess(self) -> None:
 frame = tk.Frame(self.notebook, background='white')
 self.notebook.add(frame, text='Preprocess')
 def _make_visualise(self) -> None:
 frame = tk.Frame(self.notebook, background='white')
 self.notebook.add(frame, text='Visualize')
if __name__ == '__main__':
 app = App()
 app.run()

Output

airplane

answered Apr 23, 2022 at 2:51
\$\endgroup\$
1
  • \$\begingroup\$ Thank u vary much Reinderien.... Very useful insights \$\endgroup\$ Commented Apr 23, 2022 at 7:15

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.