3
\$\begingroup\$

In my Tkinter projects I almost always end up with __init__() methods that look like this:

import tkinter as tk
from .common import ConfigPageFrame
class SystemInformationPageFrame(ConfigPageFrame):
 def __init__(self, parent, callback_dict):
 super().__init__(parent)
 self.columnconfigure(0, weight=1)
 self.rowconfigure(0, weight=1)
 self.button_text = "Refresh"
 self.button_callback = callback_dict['btn_refresh']
 self.lbl_sys_desc_text = "System description:"
 self.lbl_model_text = "Model:"
 self.lbl_serial_text = "Serial number:"
 self.lbl_mac_text = "Burned in MAC:"
 self.lbl_soft_ver_text = "Software version:"
 self.lbl_os_text = "Operating system:"
 self.lbl_net_chip_text = "Network processing device:"
 self.btn_refresh = tk.Button(self, text=button_text,
 command=button_callback)
 self.btn_refresh.grid(column=0, row=10, columnspan=2)
 self.lbl_sys_desc = tk.Label(self, text=lbl_sys_desc_text, anchor=tk.E)
 self.lbl_model = tk.Label(self, text=lbl_model_text, anchor=tk.E)
 self.lbl_serial = tk.Label(self, text=lbl_serial_text, anchor=tk.E)
 self.lbl_mac = tk.Label(self, text=lbl_mac_text, anchor=tk.E)
 self.lbl_soft_ver = tk.Label(self, text=lbl_soft_ver_text, anchor=tk.E)
 self.lbl_os = tk.Label(self, text=lbl_os_text, anchor=tk.E)
 self.lbl_net_chip = tk.Label(self, text=lbl_net_chip_text, anchor=tk.E)
 self.lbl_sys_desc.grid(column=0, row=0, sticky=tk.E)
 self.lbl_model.grid(column=0, row=1, sticky=tk.E)
 self.lbl_serial.grid(column=0, row=2, sticky=tk.E)
 self.lbl_mac.grid(column=0, row=3, sticky=tk.E)
 self.lbl_soft_ver.grid(column=0, row=4, sticky=tk.E)
 self.lbl_os.grid(column=0, row=5, sticky=tk.E)
 self.lbl_net_chip.grid(column=0, row=6, sticky=tk.E)

This sample is a GUI class from quite a large project, so I can't really show you the whole code (1700+ lines right now, tending towards much more).

As you can see, the overall structure of the widgets instantiation is very repetitive.

Is there a better way to widget instantiation? Maybe some less repetitive approach that doesn't seem to violate DRY?

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Sep 21, 2016 at 22:43
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

The answer really depends on what you're building. For example, if you're building a grid of labels and entry widgets then a simple data structure and loop is all you need. For example:

fields = [
 {"id": "sys_desc", "label": "System description", "default_value": ""},
 {"id": "model", "label": "Model", "default_value": ""},
 ...
] 
self.labels = {} 
self.entries = {} 
for field in fields:
 label = tk.Label(self, field["label"], ...)
 entry = tk.Entry(self, ...)
 entry.insert("end", field["default_value"])
 self.label[field["id"]] = label
 self.entry[field["id"] = entry
self.label["sys_desc"].grid(...)
self.entry["sys_desc"].grid(...)
...

Another solution is to create a helper class or helper function so that your code looks something like this:

self.add_widget(self, "sys_desc", "System Description", "default value...", row=1)
self.add_widget(self, "model", "Model", "default model", row=2)
self.add_widget(self, "serial", "Serial Number", "default serial value", row=3)
...

Or with classes:

self.sys_desc = LabelEntry(self, "System Description", ...)
self.model = LabelEntry(self, "Model", ...)
self.serial = LabelEntry(self, ...)
...

There is no single answer for all layouts. Complex layouts require complex code, simple layouts can be built with simple code. The bottom line is to look for patterns, and make helpers to help reduce repetitive code.

answered Sep 22, 2016 at 2:38
\$\endgroup\$

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.