Windows

In this section we present how to create new windows and how to open dialog windows.

To create a new window we define a new Window class which instantiates the Toplevel class:

class Window():
    """Create a new window."""
    def __init__(self, title='Window'):
        top = tk.Toplevel(App.root)
        top.title(title)
        frame = ttk.Frame(top, width=300, height=200, padding=(5, 10))
        frame.grid()
        App.stack.append(frame)

First we create a toplevel window and add a title to it:

top = tk.Toplevel(App.root)
top.title(title)

Then we add a themed frame widget in order to get the theme’s background color, add the geometry manager (grid) and place the frame on the widget stack, so new widgets are added to the new window:

frame = ttk.Frame(top, width=300, height=200, padding=(5, 10))
frame.pack()
App.stack.append(frame)

This is the constructor method.

    def __init__(self, title='Window', top=None):
        if top == None:
            top = tk.Toplevel(App.root)
        top.title(title)
        top.columnconfigure(0, weight=1)
        top.rowconfigure(0, weight=1)
        top.bind('<Command-i>', self.inspector)
        top.bind('<Command-p>', self.save_img)
        self.top = top

        frame = ttk.Frame(top, width=300, height=200, padding=(5, 10))
        frame.grid(sticky='nswe')

        App.stack.append(frame)
        App.win = top
        App.menus = [tk.Menu(App.win)]
        App.win['menu'] = App.menus[0]

Create new windows

The following example adds two more windows besides the root window. Each one can be closed individually, but only if the root window is closed, the application ends:

Window('Text')
Text(height=10, width=40)

Window('Canvas')
Canvas()
../_images/window1.png
"""Open multiple windows."""
from tklib import *

class Demo(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        App.root.title('Windows and dialogs')

        Button('New Window', 'Window()')
        Button('Print window geometry', 'print(App.root.geometry())')
        Button('Print window title', 'print(App.root.title())')
        Separator()
        
        Button('Resize H', 'App.root.resizable(True, False)')
        Button('Resize V', 'App.root.resizable(False, True)')
        Button('Iconify', 'App.root.iconify()')
         
        Window('Text')
        Text(height=10, width=40)

        Window('Canvas')
        Canvas()

Demo().run()

window1.py

The buttons have the following functions:

  • New Window creates a new window
  • Print window geometry prints the window placement (191x175+47+51)
  • Print window title prints the window title (Window and dialogs)
  • Resize H allows for only horizontal resizing
  • Resize V allows for only vertical resizing
  • Iconify iconifies the window

Standard dialogs

Tk provides multiple standard dialogs for

  • asking the open file name
  • asking the save file name
  • asking a directory name
  • finding a color
../_images/window2.png
"""Standard dialogs."""
from tklib import *
from tkinter import filedialog, colorchooser

class Demo(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        App.root.title('Windows and dialogs')
        Label('Standard Dialogs', font='Arial 24')

        Button('Open…', 'App.open["text"] = tk.filedialog.askopenfilename()')
        App.open = Label('File')

        Button('Save…', 'App.save["text"] = tk.filedialog.asksaveasfilename()')
        App.save = Label('File')

        Button('Directory…', 'App.dir["text"] = tk.filedialog.askdirectory()')
        App.dir = Label('Directory')

        Button('Select color…', 'App.col["text"] = tk.colorchooser.askcolor()')
        App.col = Label('Color')

Demo().run()

window2.py

Open dialog

../_images/dialog1.png

Pressing the Open… button opens a standard open file dialog and returns a path or an empty string (if cancelled).

../_images/dialog_open.png
"""Standard dialogs."""
from tklib import *

app = App('Standard dialogs')
Label('Standard Dialogs', font='Arial 24')
Button('Open…', 'App.open["text"] = filedialog.askopenfilename()')
App.open = Label('File')

app.run()

dialog1.py

Alert and confirmation dialogs

Tk provides multiple standard dialogs for showing

  • info
  • error
  • question
  • warning
../_images/window3.png
"""Alert and confirmation dialogs."""
from tklib import *
from tkinter import filedialog, messagebox

class Demo(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Label('Alert and confirmation dialogs', font='Arial 24')

        Button('Show info', 'tk.messagebox.showinfo(message="Hello world")')
        Button('Error', 'tk.messagebox.showinfo(message="Error", icon="error")')
        Button('Question', 'tk.messagebox.showinfo(message="Question", icon="question")')
        Button('Warning', 'tk.messagebox.showinfo(message="Warning", icon="warning")')
        Separator()

        types = ('ok', 'okcancel', 'yesno', 'yesnocancel', 'retrycancel', 'abortretryignore')
        for t in types:
            Button(t, 'tk.messagebox.showinfo(message="{}", type="{}")'.format(t, t))
            
Demo().run()

window3.py

Add widgets and separators

The following demo program shows how to insert buttons, labels and separators.

../_images/window4.png
"""Separators."""
from tklib import *

class Demo(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Label('Add widgets and Separators', font='Arial 24')
        Separator()

        Button('New button', 'Button()')
        Button('New label', 'Label()')
        Button('New separator', 'Separator()')
        Separator()
            
Demo().run()

window4.py

The Labelframe widget

The Labelframe widget is a frame used for grouping widgets, but has a label attached to it

../_images/window5.png
"""Add Labelframes."""
from tklib import *

class Demo(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Label('Labelframe widget', font='Arial 24')

        Labelframe(text='Frame 1', padding=5)
        Button()
        Canvas(height=100)

        App.stack.pop()

        Labelframe(text='Frame 2', padding=5)
        Button()
        Entry()

        Frame()
        Button()
        Entry()
            
Demo().run()

window5.py

Paned windows

The Panedwindow widget creates a slider and allows to change the width or hight between two or more widgets.

../_images/window6.png
"""Paned windows."""
from tklib import *

class Demo(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Label('Paned windows', font='Arial 24')

        p = Panedwindow(orient='horizontal')
        print(p)
        f1 = Canvas(background='pink')
        f2 = Canvas(background='lightblue')
        p.add(f1)
        p.add(f2)

        App.stack.pop()
        Label('Another paned window')

        p2 = Panedwindow(orient='horizontal')
        print(p2)
        p2.add(Canvas(background='yellow'))
        p2.add(Canvas(background='lightgreen'))
        p2.add(Canvas(background='orange'))
            
Demo().run()

window6.py

Tabbed notebooks

The Notebook widget creates a section with tabbed frames.

../_images/window7.png
"""Tabbed notebooks."""
from tklib import *

class Demo(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Label('Tabbed Notebooks', font='Arial 24')
        Button()
        
        Notebook()
        Frame(nb='Tab 1')
        Button()
        Frame(nb='Tab 2')
        Entry()
        Frame(nb='Tab 3')
        Canvas(height=100)
        App.stack.pop()

        Notebook()
        Frame(nb='Tab 1')
        Button()
        Button()
        Frame(nb='Tab 2')
        Entry()
        Frame(nb='Tab 3')
        Canvas(height=100)

Demo().run()

window7.py

Add more tabs

In the following example we add more tabs by clicking on a button.

../_images/window8.png
"""Tabbed Text widgets."""
from tklib import *

class Demo(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Label('Tabbed text widgets', font='Arial 24')
       
        Button('Add tab', 'Frame(nb="Tab");Text()')
        Notebook()
        Frame(nb='Tab 1')
        Text()
        Frame(nb='Tab 2')
        Text()

Demo().run()

window8.py