How I made a menu bar for Tkinter

How I made a menu bar for Tkinter

Table of contents

No heading

No headings in the article.

How I made a custom menu bar for tkinter is a story that I will like to share with you. Tkinter is a python library used in creating desktop GUI. It is very lightweight and flexible. You do not need to install anything to use tkinter if you have Python already installed.

So…. it all started on a bright day and I was bored, so I decided to start coding. I wanted to tinker with python tkinter, that was when I noticed that I could not change the menu background color. It felt weird because I have use tkinter before, but I did not pay attention to that minor detail.

I started doing research on how to fix the problem, I scouted stackoverflow and many other developers site but none could fix the problem. That went on for 2 to 3 days until I finally discovered the issue. Incase you do not know, It is a Windows issue. You can change the background and foreground on other OS like Linux and Mac, I do not know about chrome book, but I am sure they do not have that problem. So I decided to create my own tkinter menu, that will also work on other operating system.

To make one, I decided which widget was I going to use, because I wanted it to be purely tkinter. I will not be pasting any code, just snapshot. First thing I did was to make a module/library. To create a library, create a folder and add an init.py

file so python can know that that is a library. Then you start creating and adding your python file to the folder.

tkmenu.png

do not worry about the pycache, it is automatically added to your library by python. I named the file TkinterMenu.py and the custom menu Class MenuFrame. This is because I will be using a tkinter frame to create the menu. One of the challenges I had was making the frame appear and placing the button inside the frame. I could make the frame appear, but the button was always displaying outside the frame. That took me like some hours and researching to figure out. I solved that issue by inheriting from the tkinter Frame class and initializing it inside the my own menu class like this.

With out the super initialization, any button I try to add to the frame gets displayed outside the frame.

code1.png

To create the button, for the menu, I used created another class named _MenuButton, The underscore before the MenuButton is a way to make the class private. This class functions the way a normal tkinter button function. And yes I made the Menu button with the tkinter button widget.

code2.png

This is the menu button class, you will notice that I also added a super initialization to the class. This class has 4 methods which are => createMenuDropDown, addDropDownMenuButton, _displayDropDownButton, bindDropDownMenu.

The createMenuDropDown, create a popup drop down menu, where you can add more menu buttons. The addDropDownMenuButton typically just add button to the drop down menu, that was created by the createMenuDropDown function. While is a private function _displayDropDownButton gets called inside the bindDropDownMenu function to display the drop down.

The bindDropDownMenu should be called last after you are done creating you drop down menu. This function listens for left button mouse click.

code3.png

The _displayDropDownButton has an inner function named meme. which displays the drop down menu, when the menu button is clicked. This meme is wrap inside a Thread. The reason I wrap it inside a thread is to prevent the menu button from freezing, any time the popup menu is visible. This took me hours to figure out This was how I bind the _displayDropDownButton function to the mouse left click self.bind("<Button-1>", self._displayDropDownButton). You can find the link to this library in my repository