Tkinter: how to hide and show frames!

This post belongs to the serie of posts dedicated to my PyBook app to manage text files for ebooks or other purposes. This time we want to introduce a new feature to the app that hides the menu on the left. I will show you a simpler app from scratch to do that, because it would be too complicated to show you that working with the original code with a lot of existing features. In another post I will show you how I added it to the original PyBook app.

Create the app

I create the window passing it to the app App.

root = tk.Tk()
app = App(root)
root.mainloop()

The class App

The class app in the __init__ method calls the methods for the frame1 (left) and frame2 (right)

class App:

	def __init__(self, root):
		self.root = root
		self.menu()
		self.text()
		self.root.bind("<Control-l>", lambda x: self.hide())
		self.hidden = 0

The menu on the left

The frame1 contains a listbox with the files in the folder as items. I colored in black (background) and lime (fonts).

	def menu(self):
		self.frame1 = tk.Frame(self.root)
		self.frame1.pack(side="left", fill=tk.BOTH, expand=1)
		self.lb = tk.Listbox(self.frame1)
		self.lb['bg'] = "black"
		self.lb['fg'] = "lime"
		self.lb.pack(side="left", fill=tk.BOTH, expand=1)
		for file in glob.glob("*"):
			self.lb.insert(tk.END, file)

The text box on the right

There is nothing in it, because this is a simplified version of the PyBook app (watch the links below).

	def text(self):
		self.frame2 = tk.Frame(self.root)
		self.frame2.pack(side="left", fill=tk.BOTH, expand=1)
		self.txt = tk.Text(self.frame2)
		self.txt['bg'] = 'gold'
		self.txt.pack(fill=tk.BOTH, expand=1)

Binding the hide/show Frame to a key

We’ve seen this code above yet. It makes the computer call the hide() method when you press ctrl+l

		self.root.bind("<Control-l>", lambda x: self.hide())

The toggle method to hide and show the frame 1

This does the job, it uses the self.hidden boolean variable to check if the menu on the left is visible or not. It destrois the frame1 when you hit ctrl+l the first time, then destrois the frame2 also and rebuild both menu and text to show them back again. If we were using widgets, we could easily use pack_forget and pack again to hide and show the widgets. In the original App PyBook we need also to trace the selection in the menu to show back the content in the text in the right, but we will see this in the next post.

	def hide(self):
		if self.hidden == 0:
			self.frame1.destroy()
			self.hidden = 1
			print("Hidden", self.hidden)
		else:
			self.frame2.destroy()
			self.menu()
			self.text()
			self.hidden = 0
			print("Hidden", self.hidden)

The live coding at 2x speed about tkinter how to hide frames

The whole code

import tkinter as tk
import glob



class App:

	def __init__(self, root):
		self.root = root
		self.menu()
		self.text()
		self.root.bind("<Control-l>", lambda x: self.hide())
		self.hidden = 0

	def menu(self):
		self.frame1 = tk.Frame(self.root)
		self.frame1.pack(side="left", fill=tk.BOTH, expand=1)
		self.lb = tk.Listbox(self.frame1)
		self.lb['bg'] = "black"
		self.lb['fg'] = "lime"
		self.lb.pack(side="left", fill=tk.BOTH, expand=1)
		for file in glob.glob("*"):
			self.lb.insert(tk.END, file)

	def text(self):
		self.frame2 = tk.Frame(self.root)
		self.frame2.pack(side="left", fill=tk.BOTH, expand=1)
		self.txt = tk.Text(self.frame2)
		self.txt['bg'] = 'gold'
		self.txt.pack(fill=tk.BOTH, expand=1)

	def hide(self):
		if self.hidden == 0:
			self.frame1.destroy()
			self.hidden = 1
			print("Hidden", self.hidden)
		else:
			self.frame2.destroy()
			self.menu()
			self.text()
			self.hidden = 0
			print("Hidden", self.hidden)



root = tk.Tk()
app = App(root)
root.mainloop()