0

I'm trying to create a modular class ( for some gui buttons ). CoreButton should consist of most methods for a common button, including tk frame.

Goal is to inheret CoreButton - and to use its frame to build rest of button's GUI - it does not appear.

any help will be appriciated

class CoreButton(ttk.Frame):

    def __init__(self, master,nickname, hw_in=[], hw_out=[],ip_in='', ip_out='', sched_vector=[]):
        ttk.Frame.__init__(self, master)
        self.master = master
        if ip_in == '': ip_in = ip_out  # in case remote input is not defined

        self.grid()
     #####Rest of code

and class that inherits:

class ToggleBut2(CoreButton):
    def __init__(self, master, hw_in=[], hw_out=[],ip_in='', ip_out='', sched_vector=[]):
        CoreButton.__init__(self, master, nickname="JOHM", hw_in=hw_in, hw_out=hw_out, ip_in=ip_in, ip_out=ip_out, sched_vector=sched_vector)
        self.master = master

    def build_gui(self, nickname='babe', height=3, width=13):

        self.button = tk.Checkbutton(self, text=nickname, variable=self.but_var, indicatoron=0, height=height, width=width, command=self.sf_button_press)
        self.button.grid(row=0, column=0)
6
  • 1
    It's a bad idea to create a reusable component that calls self.grid -- it limits the reuse only to parent/master widgets that use grid. Commented Dec 16, 2017 at 12:59
  • 2
    I don't see anywhere where you call build_gui. Commented Dec 16, 2017 at 13:01
  • Can you explain why is bad idea Commented Dec 16, 2017 at 13:02
  • 1
    I did in my comment: it limits the reuse only to parent/master widgets that use grid. You can't use it if the parent is using pack or place, 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. Commented Dec 16, 2017 at 13:09
  • 2
    you don't need self.master = master because Frame already does it. Commented Dec 16, 2017 at 13:39

1 Answer 1

2

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()

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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.