tnnvrr
tnnvrr

Reputation: 1

How to create a sidebar with buttons to hide and show frames in Tkinter

I'm trying to create a basic application which has a sidebar that contains menu buttons. When each button is pressed, it changes the contents of the main content area to display the relevant content. I have created the layout, shown below. For reference, I have also added a wireframe of how I want the GUI to look.

The problem is that I cannot get the buttons to hide/unhide the relevant frames. How would this be done? And a further question, how would I embed a matplotlib chart into one of these frames? More specifically, when I press the 'Markets' button, the program would display a matplotlib chart of the Facebook stock, using an API. Any help would be appreciated.

import tkinter as tk
from tkinter import *
from tkinter import ttk
from tkinter.ttk import *

# Define the function for raising a frame ontop of another, in order for the 
# respective frame to be displayed in the mainarea
def raise_frame(frame):
    frame.tkraise()

# Initialise the tkinter root window, name it, and set its size
root = Tk() 
root.geometry('500x500')
root.title('Stock Trading Simulator')


# Create the tkinter frame for the sidebar, and place it in the root window
sidebar = tk.Frame(root, width=200, bg='white', height=500, relief='raised', borderwidth=2)
sidebar.pack(expand=False, fill='both', side='left', anchor='nw')

# Create the tkinter frame for the main content area
mainarea = tk.LabelFrame(root, bg='#CCC', width=500, height=500)
mainarea.pack(expand=True, fill='both', side='right')

# Create the tkinter frame for the market
marketFrame = tk.Frame(mainarea, relief='sunken', bg='Red')

# Create the tkinter frame for the portfolio
portfolioFrame = Frame(mainarea, relief='sunken')

# Create the tkinter frame for the portfolio pending orders
pendingOrdersFrame = Frame(mainarea, relief='sunken')

# Create the tkinter frame for the portfolio trade history 
tradeHistoryFrame = Frame(mainarea, relief='sunken')

for frame in (marketFrame, portfolioFrame, pendingOrdersFrame, tradeHistoryFrame):
    frame.grid(row=0, column=0, sticky='news')

# Create button widgets for sidebar 
btnMarket = Button(sidebar, text = 'Markets',
                    command=lambda:raise_frame(marketFrame)).grid(row = 0, column = 0,)


btnPortfolio = Button(sidebar, text = 'Portfolio',)
                
                
btnPortfolioSummary = Button(sidebar, text = 'Summary',)
                

btnPortfolioPendingOrders = Button(sidebar, text = 'Pending Orders',)
                

btnPortfolioTradeHistory = Button(sidebar, text = 'Trade History',)
                
# Map buttons to the tkinter grid to display them in the sidebar frame
btnPortfolio.grid(row = 2, column = 0)
btnPortfolioSummary.grid(row = 3, column = 0, padx=(15,0))
btnPortfolioPendingOrders.grid(row = 4, column = 0, padx=(15,0))
btnPortfolioTradeHistory.grid(row = 5, column = 0, padx=(15,0))


root.mainloop()

Upvotes: 0

Views: 1807

Answers (1)

Mrkalvin Bs
Mrkalvin Bs

Reputation: 113

See the example, to make other frames just follow the model : frm_ctt_(...).py

Note: I suggest you install and use ttkbootstrap

python -m pip install git+https://github.com/israel-dryer/ttkbootstrap

main.py

from tkinter import *
#from tkinter import ttk
from ttkbootstrap import ttk
from frm_ctt_0 import *

#python -m pip install git+https://github.com/israel-dryer/ttkbootstrap
#pip3 install git+https://github.com/israel-dryer/ttkbootstrap
#https://ttkbootstrap.readthedocs.io/en/latest/gettingstarted/installation/



#class Functions(Tk):
class Functions(ttk.Window):
    def unload_frame_content(self):
        #self.panedwindow_left.remove(self.frame_content)
        self.frame_content.pack_forget()
        return


    def load_content_0(self, event=None):
        self.unload_frame_content()
        self.frame_right0()
        return

    def load_content_1(self, event=None):
        self.unload_frame_content()
        self.frame_right1()
        return


class MainFrame(Functions):
    def __init__(self):
        #Tk.__init__(self)
        ttk.Window.__init__(self, themename='pulse')

        self.geometry('500x300')
        self.title('Tkinter')
        
        self.set_frame_left()
        self.frame_right0()
        return


    def set_frame_left(self):
        self.frame_left = ttk.Frame(self)
        self.frame_left.pack(side=LEFT, fill=Y)

        self.frame_ctt_left = ttk.Frame(self.frame_left, bootstyle='info')
        self.frame_ctt_left.pack(fill=BOTH, expand=1, ipadx=10)
        
        self.btn0 = ttk.Button(self.frame_ctt_left, text='One', command=self.load_content_0)
        self.btn0.pack(pady=2)
        self.btn1 = ttk.Button(self.frame_ctt_left, text='Two', command=self.load_content_1)
        self.btn1.pack(pady=2)
        return


    def frame_right0(self):
        self.frame_content = ttk.Frame(self)
        self.frame_content.pack(fill=BOTH, expand=1)
        #self.panedwindow_left.add(self.frame_content)

        data= {'var_text': 'Hellow World!'}
        self.ctt = Content0(self.frame_content, data=data)
        self.ctt.pack(fill=BOTH, expand=1)
        return


    def frame_right1(self):
        self.frame_content = ttk.Frame(self)
        self.frame_content.pack(fill=BOTH, expand=1)
        #self.panedwindow_left.add(self.frame_content)
        
        ttk.Label(self.frame_content, text='Content Two').pack()
        return

if __name__== '__main__':
    app = MainFrame()
    app.mainloop()

frm_ctt_0.py

from tkinter import *
import ttkbootstrap as ttk

class Func(ttk.Frame):
    def test(self):
        print('hi')


class Content0(Func):
    def __init__(self, parent, *args, **kwargs):

        self.data = kwargs.pop('data', None)

        ttk.Frame.__init__(self, parent, *args, **kwargs)

        self.set_widgets()
        return


    def set_widgets(self):
        self.frm_r = ttk.Frame(self)
        self.frm_r.place(relx=0, rely=0, relwidth=1, relheight=1)

        self.frm_r_top = ttk.Frame(self.frm_r)
        self.frm_r_top.pack(side=TOP)

        ttk.Label(self.frm_r_top, text=self.data['var_text']).pack()
        self.btn = ttk.Button(self.frm_r_top, text='Click', command=self.test)
        self.btn.pack()

Upvotes: 1

Related Questions