• Re: Tkinter module test: widget class not inserted in application frame

    From Rich Shepard@21:1/5 to MRAB on Fri Jun 17 10:06:12 2022
    On Fri, 17 Jun 2022, MRAB wrote:

    You haven't shown the code for common_classes.LabelInput, but I'm guessing that the first argument should be the parent.

    Here's the LabelInput class:
    class LabelInput(tk.Frame):
    """ A widget containing a label and input together. """

    def __init__(self, parent, label='', input_class=ttk.Entry,
    input_var=None, input_args=None, label_args=None,
    **kwargs):
    super().__init__(parent, **kwargs)
    label_args = label_args or {}
    input_args = input_args or {}
    self.variable = input_var,

    if input_class in (ttk.Checkbutton, ttk.Button, ttk.Radiobutton):
    input_args["text"] = label
    input_args["variable"] = input_var
    else:
    self.label = ttk.Label(self, text=label, **label_args)
    self.label.grid(row=0, column=0, sticky=(tk.W + tk.E))
    input_args["textvariable"] = input_var

    self.input = input_class(self, **input_args)
    self.input.grid(row=1, column=0, sticky=(tk.W + tk.E))
    self.columnconfigure(0, weight=1)
    self.error = getattr(self.input, 'error', tk.StringVar())
    self.error_label = ttk.Label(self, textvariable=self.error)
    self.error_label.grid(row=2, column=0, sticky=(tk.W + tk.E))

    def grid(self, sticky=(tk.E + tk.W), **kwargs):
    super().grid(sticky=sticky, **kwargs)

    def get(self):
    try:
    if self.variable:
    return self.variable.get()
    elif type(self.input) == tk.Text:
    return self.input.get('1.0', tk.END)
    else:
    return self.input.get()
    except (TypeError, tk.TclError):
    # happens when numeric fields are empty.
    return ''

    def set(self, value, *args, **kwargs):
    if type(self.variable) == tk.BooleanVar:
    self.variable.set(bool(value))
    elif self.variable:
    self.variable.set(value, *args, **kwargs)
    elif type(self.input) in (ttk.Checkbutton, ttk.Radiobutton):
    if value:
    self.input.select()
    else:
    self.input.deselect()
    elif type(self.input) == tk.Text:
    self.input.delete('1.0', tk.END)
    self.input.insert('1.0', value)
    else:
    self.input.delete(0, tk.END)
    self.input.insert(0, value)

    You're passing in the _class_ ConactNameInput, but I'm guessing that it should be an _instance_ of that class, in this case, 'self'.

    Haven't I done this in the application class?
    class NameApplication(tk.Tk):
    def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.title("Contact Name")
    self.geometry("800x600")
    self.resizable(width = False, height = False)
    ContactNameInput(self).grid(row = 0, column = 0, sticky=('EWNS'))
    self.columnconfigure(0, weight=1)

    If not, where do I specify the instance of the ContactNameInput class?

    Thanks,

    Rich


    --
    Richard Shepard, Ph.D. The Environmental Issues Doctor
    Applied Ecosystem Services, LLC
    Troutdale, OR 97060 USA 503-667-4517 www[dot]appl-ecosys[dot]com

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich Shepard@21:1/5 to All on Fri Jun 17 09:19:59 2022
    I'm not seeing the error source in a small tkinter module I'm testing.

    The module code:
    -----------
    import tkinter as tk
    from tkinter import ttk

    import common_classes as cc

    class ConactNameInput(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
    super().__init__(parent, *args, **kwargs)
    # A dict to keep track of input widgets
    self.inputs = {}

    self.inputs['Last name'] = cc.LabelInput(
    ContactNameInput, 'lname',
    input_class = ttk.Entry,
    input_var = tk.StringVar()
    )
    self.inputs['Last name'].grid(row = 0, column = 0)
    #
    self.inputs['First name'] = cc.LabelInput(
    ContactNameInput, 'fname',
    input_class = ttk.Entry,
    input_var = tk.StringVar()
    )
    self.inputs['First name'].grid(row = 0, column = 1)

    okay_button = tk.Button(self, text="OK",
    command=self.ok)
    okay_button.pack(side=tk.LEFT, padx=(20, 0), pady=(0, 20))

    cancel_button = tk.Button(self, text="Cancel",
    command=self.cancel)
    cancel_button.pack(side=tk.RIGHT, padx=(0, 20), pady=(0, 20))

    def okay_button(self):
    pass

    def cancel_button(self):
    Quitter()

    def get_last_name(self):
    pass

    def get_first_name(self):
    pass


    class NameApplication(tk.Tk):
    def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.title("Contact Name")
    self.geometry("800x600")
    self.resizable(width = False, height = False)
    ContactNameInput(self).grid(row = 0, column = 0, sticky=('EWNS'))
    self.columnconfigure(0, weight=1)

    if __name__ == '__main__':
    app = NameApplication()
    app.mainloop()
    ----------

    The python error traceback:
    ----------
    Traceback (most recent call last):
    File "contact_history_name_input.py", line 60, in <module>
    app = NameApplication()
    File "contact_history_name_input.py", line 55, in __init__
    ContactNameInput(self).grid(row = 0, column = 0, sticky=('EWNS'))
    File "contact_history_name_input.py", line 17, in __init__
    input_var = tk.StringVar()
    File "/home/rshepard/development/BusinessTracker/views/common_classes.py", line 46, in __init__
    super().__init__(parent, **kwargs)
    File "/usr/lib64/python3.7/tkinter/__init__.py", line 2744, in __init__
    Widget.__init__(self, master, 'frame', cnf, {}, extra)
    File "/usr/lib64/python3.7/tkinter/__init__.py", line 2292, in __init__
    BaseWidget._setup(self, master, cnf)
    File "/usr/lib64/python3.7/tkinter/__init__.py", line 2262, in _setup
    self.tk = master.tk
    AttributeError: type object 'ContactNameInput' has no attribute 'tk'
    ----------

    I'm not correctly placing the NameInput class in the NameApplication frame. What have I missed?

    Rich

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From MRAB@21:1/5 to Rich Shepard on Fri Jun 17 17:47:24 2022
    On 2022-06-17 17:19, Rich Shepard wrote:
    I'm not seeing the error source in a small tkinter module I'm testing.

    The module code:
    -----------
    import tkinter as tk
    from tkinter import ttk

    import common_classes as cc

    class ConactNameInput(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
    super().__init__(parent, *args, **kwargs)
    # A dict to keep track of input widgets
    self.inputs = {}

    self.inputs['Last name'] = cc.LabelInput(
    ContactNameInput, 'lname',
    input_class = ttk.Entry,
    input_var = tk.StringVar()
    )
    self.inputs['Last name'].grid(row = 0, column = 0)
    #
    self.inputs['First name'] = cc.LabelInput(
    ContactNameInput, 'fname',
    input_class = ttk.Entry,
    input_var = tk.StringVar()
    )
    self.inputs['First name'].grid(row = 0, column = 1)

    okay_button = tk.Button(self, text="OK",
    command=self.ok)
    okay_button.pack(side=tk.LEFT, padx=(20, 0), pady=(0, 20))

    cancel_button = tk.Button(self, text="Cancel",
    command=self.cancel)
    cancel_button.pack(side=tk.RIGHT, padx=(0, 20), pady=(0, 20))

    def okay_button(self):
    pass

    def cancel_button(self):
    Quitter()

    def get_last_name(self):
    pass

    def get_first_name(self):
    pass


    class NameApplication(tk.Tk):
    def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.title("Contact Name")
    self.geometry("800x600")
    self.resizable(width = False, height = False)
    ContactNameInput(self).grid(row = 0, column = 0, sticky=('EWNS'))
    self.columnconfigure(0, weight=1)

    if __name__ == '__main__':
    app = NameApplication()
    app.mainloop()
    ----------

    The python error traceback:
    ----------
    Traceback (most recent call last):
    File "contact_history_name_input.py", line 60, in <module>
    app = NameApplication()
    File "contact_history_name_input.py", line 55, in __init__
    ContactNameInput(self).grid(row = 0, column = 0, sticky=('EWNS'))
    File "contact_history_name_input.py", line 17, in __init__
    input_var = tk.StringVar()
    File "/home/rshepard/development/BusinessTracker/views/common_classes.py", line 46, in __init__
    super().__init__(parent, **kwargs)
    File "/usr/lib64/python3.7/tkinter/__init__.py", line 2744, in __init__
    Widget.__init__(self, master, 'frame', cnf, {}, extra)
    File "/usr/lib64/python3.7/tkinter/__init__.py", line 2292, in __init__
    BaseWidget._setup(self, master, cnf)
    File "/usr/lib64/python3.7/tkinter/__init__.py", line 2262, in _setup
    self.tk = master.tk
    AttributeError: type object 'ContactNameInput' has no attribute 'tk' ----------

    I'm not correctly placing the NameInput class in the NameApplication frame. What have I missed?

    You haven't shown the code for common_classes.LabelInput, but I'm
    guessing that the first argument should be the parent.

    You're passing in the _class_ ConactNameInput, but I'm guessing that it
    should be an _instance_ of that class, in this case, 'self'.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From MRAB@21:1/5 to Rich Shepard on Fri Jun 17 19:28:12 2022
    On 2022-06-17 18:06, Rich Shepard wrote:
    On Fri, 17 Jun 2022, MRAB wrote:

    You haven't shown the code for common_classes.LabelInput, but I'm guessing >> that the first argument should be the parent.

    [snip]
    You're passing in the _class_ ConactNameInput, but I'm guessing that it
    should be an _instance_ of that class, in this case, 'self'.

    Haven't I done this in the application class?
    class NameApplication(tk.Tk):
    def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.title("Contact Name")
    self.geometry("800x600")
    self.resizable(width = False, height = False)
    ContactNameInput(self).grid(row = 0, column = 0, sticky=('EWNS'))
    self.columnconfigure(0, weight=1)

    If not, where do I specify the instance of the ContactNameInput class?

    This:

    self.inputs['Last name'] = cc.LabelInput(
    ContactNameInput, 'lname',
    input_class = ttk.Entry,
    input_var = tk.StringVar()
    )

    should be this:

    self.inputs['Last name'] = cc.LabelInput(
    self, 'lname',
    input_class = ttk.Entry,
    input_var = tk.StringVar()
    )

    Also, this:

    self.inputs['First name'] = cc.LabelInput(
    ContactNameInput, 'fname',
    input_class = ttk.Entry,
    input_var = tk.StringVar()
    )

    should be this:

    self.inputs['First name'] = cc.LabelInput(
    self, 'fname',
    input_class = ttk.Entry,
    input_var = tk.StringVar()
    )

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich Shepard@21:1/5 to MRAB on Fri Jun 17 11:54:19 2022
    On Fri, 17 Jun 2022, MRAB wrote:

    This:

    self.inputs['Last name'] = cc.LabelInput(
    ContactNameInput, 'lname',
    input_class = ttk.Entry,
    input_var = tk.StringVar()
    )

    should be this:

    self.inputs['Last name'] = cc.LabelInput(
    self, 'lname',
    input_class = ttk.Entry,
    input_var = tk.StringVar()
    )

    Also, this:

    self.inputs['First name'] = cc.LabelInput(
    ContactNameInput, 'fname',
    input_class = ttk.Entry,
    input_var = tk.StringVar()
    )

    should be this:

    self.inputs['First name'] = cc.LabelInput(
    self, 'fname',
    input_class = ttk.Entry,
    input_var = tk.StringVar()
    )

    MRAB,

    Ah! I must have misread Alan Moore's examples, then. I'll need to fix all my views.

    Thank you,

    Rich

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dennis Lee Bieber@21:1/5 to All on Fri Jun 17 20:45:49 2022
    On Fri, 17 Jun 2022 09:19:59 -0700 (PDT), Rich Shepard <rshepard@appl-ecosys.com> declaimed the following:

    I'm not seeing the error source in a small tkinter module I'm testing.

    The module code:
    -----------
    import tkinter as tk
    from tkinter import ttk

    import common_classes as cc

    class ConactNameInput(tk.Frame):

    Presuming this is a cut&paste of the actual code...

    ContactNameInput, 'lname',

    ContactNameInput, 'fname',


    ContactNameInput(self).grid(row = 0, column = 0, sticky=('EWNS'))

    ... please compare the spelling!



    --
    Wulfraed Dennis Lee Bieber AF6VN
    wlfraed@ix.netcom.com http://wlfraed.microdiversity.freeddns.org/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich Shepard@21:1/5 to Dennis Lee Bieber on Fri Jun 17 19:47:38 2022
    On Fri, 17 Jun 2022, Dennis Lee Bieber wrote:

    ContactNameInput, 'lname',
    ContactNameInput, 'fname',

    This works if a tk.labelframe is where the widget is placed. In my case, as MRAB taught me, the proper syntax is
    self,'lname'...
    self.'fname'...

    Thanks, Dennis,

    Rich

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter J. Holzer@21:1/5 to Rich Shepard on Sat Jun 18 10:10:34 2022
    On 2022-06-17 19:47:38 -0700, Rich Shepard wrote:
    On Fri, 17 Jun 2022, Dennis Lee Bieber wrote:

    ContactNameInput, 'lname',
    ContactNameInput, 'fname',

    This works if a tk.labelframe is where the widget is placed. In my case, as MRAB taught me, the proper syntax is
    self,'lname'...

    There is a comma (U+002C) here ...

    self.'fname'...

    And a dot (U+002E) here.

    I don't think this is correct.

    I would also recommend to always add a space after a comma.

    hp

    --
    _ | Peter J. Holzer | Story must make more sense than reality.
    |_|_) | |
    | | | hjp@hjp.at | -- Charles Stross, "Creative writing
    __/ | http://www.hjp.at/ | challenge!"

    -----BEGIN PGP SIGNATURE-----

    iQIzBAABCgAdFiEETtJbRjyPwVTYGJ5k8g5IURL+KF0FAmKtiHUACgkQ8g5IURL+ KF2bRBAAihOQek4C3L3gdqg3MV/4Hq7n7Ys5XQedDaz4SufDyUbS+OVRg0Tt3uCx 9KGa0vzvkCSk1ndyBByki228fDjgrRZ+zhvHr8C7m9i9mdzolHuMC2icq8NG7Sps Vo+cOBmegjo/4/7oH6jWTKZm6r7aGE5WAsfMwNWIc3NZ+VvX8pcqxWzcOT11wJz/ aRQtogp4ow7EDY908iZWJqtmz9EAbWuLV7Tc1zDrkG7wO7y9jgN3bQF9ARMC4Cwo hHslYJGhv8i5P8Fn7scGyuSVeMIjvQ1TR98OIayf+F85ObLVNap2TUjLeBWikfE2 z1gR9ZJvrK5ngLoVvx0nxs2otQWlCSaOmvOulBCrNC3cir5GG/pTcVVjZp4GpXoP emSqrQhD012qK44WmJ1awETiKyACiSZRMSDMoSSY78Ab/xkNKgz+Zz2QkLEzA7aK 89MdehOCghlGRDu/nL3PflsM5V13yvlVVa6sFCenLrsIixFL1hv94wbMAScL2XtT qeAAlQEgW5Xws9BgxrlGVNreVnDysINGOay1aHkgf2KmjHIYL1SWP1mvZ16A4gjp 65SmqVTQa9zhmObdH/wCjJinmJSVp3H++Qr1MmT6WsRqtGHVRBkHpZwzzwxnSzaW Dp9+Ik7o1D4ZFPOvLn4roLq/vxncfeAqz9ahaLs
  • From Rich Shepard@21:1/5 to Peter J. Holzer on Sat Jun 18 05:06:22 2022
    On Sat, 18 Jun 2022, Peter J. Holzer wrote:

    There is a comma (U+002C) here ...
    And a dot (U+002E) here.

    That was a typo when I wrote the message. And I usually add a space after commas and surrounding equal signs, all for easier reading.

    Thank you,

    Rich

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)