Reputation: 127
I've been trying to create a custom widget in tkinter, nothing too fancy, just a frame that holds an entry and two labels. I want the labels and the frame to be able to access StringVars of the parent application (ie. the textvariables for both of the labels, and the entry textvariable as well). I thought this should be fairly straightforward to do by passing these names through the initialization method as keyword args, but I'm running into trouble. Here's my code:
import tkinter as tk
import tkinter.ttk as ttk
class EntryFrame(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.title = kwargs.get('title')
title = tk.Label(self, text=self.title)
unit = tk.Label(self, text='(Unit)')
self.entryVar = tk.StringVar()
entry = tk.Entry(self, textvariable=self.entryVar)
title.grid(row=0, column=0, sticky='es')
unit.grid(row=0, column=1, sticky='ws')
entry.grid(row=1, column=0, columnspan=2, padx=3, pady=3, sticky='n')
class TestApplication(tk.Frame):
def __init__(self, master=None, *args, **kwargs):
tk.Frame.__init__(self, master=None, *args, **kwargs)
self.master=master
self.grid(row=0, column=0)
entryFrame = EntryFrame(self, title='Title')
entryFrame.grid(row=0, column=0)
root = tk.Tk()
Application = TestApplication(root)
root.mainloop()
I'm running into a problem where I can't actually pass anything else to my new widget, because it initializes with tk.Frame it seems to only want tk.frame attributes upon init. I can't actually give it args or kwargs.
If I try a different approach:
class EntryBox(self):
def __init__(self, parent, *args, **kwargs):
self.frame = tk.Frame(self)
self.title = tk.Label(self, text='Title')
self.unit = tk.Label(self, text='(Unit)')
self.entryVar = tk.StringVar()
entry = tk.Entry(self, textvariable=self.EntryVar)
title.grid(row=0, column=0, sticky='es')
unit.grid(row=0, column=1, sticky='es')
entry.grid(row=1, column=0, columnspan=2, padx=3, pady=3, sticky='n')
The class throws errors about self not being defined.
EDIT:
A better example of code sample 2:
class EntryBox():
def __init__(self, parent, *args, **kwargs):
self.title=kwargs.pop('title')
self.frame = tk.Frame(parent)
self.frame.grid(row=0, column=0)
self.title = tk.Label(self.frame, text=self.title)
self.unit = tk.Label(self.frame, text='(Unit)')
self.entryVar = tk.StringVar()
self.entry = tk.Entry(self.frame)
self.title.grid(row=0, column=0, sticky='es')
self.unit.grid(row=0, column=1, sticky='es')
self.entry.grid(row=1, column=0, columnspan=2, padx=3, pady=3, sticky='n')
Upvotes: 0
Views: 1551
Reputation: 9622
Try something like:
def __init__(self, parent, title, **kwargs):
tk.Frame.__init__(self, parent, **kwargs)
self.title = title
In other words, avoid passing on your custom parameters to the superclass.
Or you could do self.title = kwargs.pop('title')
BEFORE calling the superclass's __init__
.
Your second code sample is simply confused - in class EntryBox(self):
, what were you expecting 'self' to be?
Upvotes: 1