I don't know what you try to do but I would do something like this
I don't use self.grid() inside class, so outside class I can use tb1.pack() or tb1.grid() depends on which layout manager I use in window.
In __init__ I execute self.build_gui() so I don't have to do it manually, but now all classes have to create self.build_gui() without arguments.
I add Label only for test - to display "selected"/"not selected". You don't need it.
import tkinter as tk
from tkinter import ttk
class CoreButton(ttk.Frame):
def __init__(self, master, nickname, hw_in=None, hw_out=None, ip_in=None, ip_out=None, sched_vector=None):
ttk.Frame.__init__(self, master)
self.nickname = nickname
self.hw_in = hw_in
if self.hw_in is None:
self.hw_in = []
#self.hw_in = hw_in or []
self.hw_out = hw_out
if self.hw_out is None:
self.hw_out = []
#self.hw_out = hw_out or []
self.ip_out = ip_out
self.ip_in = ip_in
if self.ip_in is None:
self.ip_in = self.ip_out # in case remote input is not defined
#self.ip_in = hw_in or self.ip_out
self.sched_vector = sched_vector
if sched_vector is None:
sched_vector = []
#self.sched_vector = sched_vector or []
self.build_gui() # <--- to build it automatically
def build_gui(self):
# you will overide it in child widgets
raise NotImplementedError('You have to override method build_gui()')
class ToggleBut2(CoreButton):
def __init__(self, master, hw_in=None, hw_out=None, ip_in=None, ip_out=None, sched_vector=None, height=3, width=13):
self.height = height
self.width = width
# `self.but_var` is used in `build_gui` so it has to be created before `__init__` which executes `build_gui`
# or create it directly in `build_gui`
#self.but_var = tk.StringVar()
CoreButton.__init__(self, master, "JOHM", hw_in, hw_out, ip_in, ip_out, sched_vector)
def build_gui(self, nickname='babe'):
self.but_var = tk.IntVar()
self.button = tk.Checkbutton(self, text=self.nickname, variable=self.but_var, indicatoron=0, height=self.height, width=self.width, command=self.sf_button_press)
self.button.grid(row=0, column=0)
self.label = tk.Label(self, text='[not selected]')
self.label.grid(row=1, column=0)
def sf_button_press(self):
print(self.but_var.get())
if self.but_var.get() == 0:
self.label['text'] = '[ not selected ]'
else:
self.label['text'] = '[ selected ]'
# --- main ---
root = tk.Tk()
tb1 = ToggleBut2(root, height=1, width=10)
tb1.pack()
tb2 = ToggleBut2(root, height=3, width=30)
tb2.pack()
tb2 = ToggleBut2(root, height=5, width=50)
tb2.pack()
root.mainloop()

self.grid-- it limits the reuse only to parent/master widgets that usegrid.build_gui.grid. You can't use it if the parent is usingpackorplace, or trying to place the widget in a text or canvas widget. It tightly couples the widget to the implementation of the code that creates it.self.master = masterbecauseFramealready does it.