Home > Software design >  tkinter oo - how to iconify a top-level window linking to a button widget
tkinter oo - how to iconify a top-level window linking to a button widget

Time:08-13

I am working with python 3.8, macos Big Sur.

from tkinter import *

def test(window):
    window.iconify()

def onclick():
    window = Toplevel()
    window.geometry(" 300 300")
    window.title("child window")
    Button(window, text="click", command=lambda: test(window)).pack()
    window.mainloop()

root = Tk()
root.title("parent window")
root.geometry("300x200 200 200")
root.resizable(False, False)
root.iconbitmap("tools.ico")

Button(root, text="open child window", command=onclick).pack()

root.mainloop()

I am trying to rewrite the code above as a class, like:

import tkinter as tk
from tkinter import ttk

class GUI:

    def __init__(self):
        self.root = tk.Tk()
        self.root.title('title')
        self.root.geometry("300x200 500 250")
        self.root.resizable(False, False)
        self.interface()
        self.root.iconbitmap("tools.ico")

    def interface(self):
        self.btn = tk.Button(self.root, text="open child window", command=self.onclick).pack()

    def onclick(self):
        window = tk.Toplevel()
        window.geometry('200x100 500 250')
        window.title('child window')
        self.btn = tk.Button(window, text="click", command=lambda window: self.test(*window)).pack()

        window.mainloop()

    def test(self, window):
        window.iconify()

if __name__ == '__main__':
    gui = GUI()
    gui.root.mainloop()

however, it ends with

Traceback (most recent call last):
  File "/Applications/miniconda3/lib/python3.8/tkinter/__init__.py", line 1892, in __call__
    return self.func(*args)
TypeError: <lambda>() missing 1 required positional argument: 'window'

I also have tried binding an iconify event with button, like:

import tkinter as tk
from tkinter import ttk

class GUI:

    def __init__(self):
        self.root = tk.Tk()
        self.root.title('title')
        self.root.geometry("300x200 500 250")
        self.root.resizable(False, False)
        self.interface()
        self.root.iconbitmap("tools.ico")

    def interface(self):
        self.btn = tk.Button(self.root, text="open child window", command=self.onclick).pack()

    def onclick(self):
        window = tk.Toplevel()
        window.geometry('200x100 500 250')
        window.title('child window')
        self.btn = tk.Button(window, text="click")
        self.btn.pack()
        self.btn.bind("<Button-1>", self.test(window=window))

        window.mainloop()

    def test(self, window):
        window.iconify()

if __name__ == '__main__':
    gui = GUI()
    gui.root.mainloop()

just did not work either.

I would appreciate if anyone point out how I could work with lambda: window in the first example code given above.


==2022/8/13==:

class GUI:

    def __init__(self):
        self.root = tk.Tk()
        self.root.title('title')
        self.root.geometry("300x200 500 250")
        self.root.resizable(False, False)
        self.interface()
        self.root.iconbitmap("tools.ico")

    def interface(self):
        btnopen = tk.Button(self.root, text="open child window", command=self.onclick).pack()

    def onclick(self):
        window = tk.Toplevel()
        window.geometry('200x100 500 250')
        window.title('child window')
        btnclick = tk.Button(window, text="click", command=lambda: self.test(window)).pack()

        window.mainloop()

    def test(self, window):
        window.iconify()
        window.deiconify()

if __name__ == '__main__':
    gui = GUI()
    gui.root.mainloop()

pass with the code above... a low class mistake I made is that I defined 2 self.btn. Besides, it should work with lambda: self.test(window).

CodePudding user response:

If all you are looking to do is iconify() the window then why not just use that in the command? No need to separate it as its own method. Is this what you are looking for?

import tkinter as tk
from tkinter import ttk

class GUI:

    def __init__(self):
        self.root = tk.Tk()
        self.root.title('title')
        self.root.geometry("300x200 500 250")
        self.root.resizable(False, False)
        self.interface()
        #self.root.iconbitmap("tools.ico")

    def interface(self):
        self.btn = tk.Button(self.root, text="open child window", command=self.onclick)
        self.btn.pack()

    def onclick(self):
        window = tk.Toplevel()
        window.geometry('200x100 500 250')
        window.title('child window')
        self.btn = tk.Button(window, text="click", command=lambda: window.iconify())
        self.btn.pack()


if __name__ == '__main__':
    gui = GUI()
    gui.root.mainloop()
  • Related