Python Forum
[Tkinter] Frame with treeview
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Frame with treeview
#1
Hi all,

I am a new to Python but i can see possibilities that can make job easier!

Can someone point me in the correct direction please?

Attached is a test file I have been playing with. On one side I have a treeview and on the other is a frame. The frame should change based on the treeview node i select. How do i get it to do that?

Any help would be appreciated.

Regards
V
Larz60+ write May-24-2021, 12:40 PM:
Please don't attach code, rather paste in post also output and errors (in it's entirety) between their respective tags. Refer to BBCode help topic on how to post.
Then use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.

Attached Files

.py   FRAME_PY.py (Size: 826 bytes / Downloads: 366)
Reply
#2
Hi,

************ reposting question as the the forum rules ***********

The code below creates a treeview and frame. Can someone help create some forms that will open in the frame when selecting a treeview node.

i.e when I select A in the treeview node, Form A is then called in the frame and so on....

How is this accomplished in python?

from tkinter import *
from tkinter import ttk
root = Tk()
root.title('Test')
root.iconbitmap()           
PW = ttk.PanedWindow(root, orient=HORIZONTAL)
PW.pack(fill=BOTH, expand=True)

def my_cfm():
    my_label = label(f2,bg=red)
    my_label.pack()

f1 = ttk.Frame(PW, width=75, height=300, relief=SUNKEN)
f2 = ttk.Frame(PW, width=400, height=300, relief=SUNKEN)
PW.add(f1, weight=0)
PW.add(f2, weight=4)
tv = ttk.Treeview(f1)
tv.pack()
tv.insert('', '0', 'item1', text='PRODUCT')

tv.insert('item1', '0', 'A', text='A')

tv.insert('item1', '1', 'B', text='B')
tv.insert('item1', '2', 'C', text='C')
tv.insert('item1', '3', 'D', text='D')
tv.insert('', '1', 'item2', text='REPORTS')

tv.insert('', '3', 'item3', text='QUERIES')
tv.config(height=100)

root.state('zoomed')

tv.mainloop()
Thanks
Reply
#3
Bind an event handler to the treeview event '<<TreeviewSelect>>'
In the event handler change the frame based on the treeview selection.
Here is modified example of your code.
import tkinter as tk
from tkinter import ttk


class App(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title('Test')
        self.iconbitmap()
        self.state('zoomed')
        paned_window = ttk.PanedWindow(self, orient=tk.HORIZONTAL)
        self.tree_view_frame = TreeviewFrame(
            paned_window, width=75, height=300, relief=tk.SUNKEN)
        self.tree_view_frame.tree_view.bind(
            '<<TreeviewSelect>>', self.on_tree_view_select)
        self.display_frame = DisplayFrame(
            paned_window, width=400, height=300, relief=tk.SUNKEN)
        paned_window.add(self.tree_view_frame, weight=0)
        paned_window.add(self.display_frame, weight=4)
        paned_window.pack(fill=tk.BOTH, expand=True)

    def on_tree_view_select(self, event):
        frame_id = self.tree_view_frame.tree_view.selection()
        self.display_frame.change_frame(frame_id)


class TreeviewFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        tree_view = ttk.Treeview(self)
        tree_view.pack()
        tree_view.insert('', '0', 'item1', text='PRODUCT')

        tree_view.insert('item1', '0', 'A', text='A')

        tree_view.insert('item1', '1', 'B', text='B')
        tree_view.insert('item1', '2', 'C', text='C')
        tree_view.insert('item1', '3', 'D', text='D')
        tree_view.insert('', '1', 'item2', text='REPORTS')

        tree_view.insert('', '3', 'item3', text='QUERIES')
        tree_view.config(height=100)
        self.tree_view = tree_view


class DisplayFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # self.config(bg='Red')
        self.frames = {('item1',): ProductFrame(self),
                       ('A',): AFrame(self),
                       ('B',): BFrame(self),
                       ('C',): CFrame(self),
                       ('D',): DFrame(self),
                       ('item2',): ReportsFrame(self),
                       ('item3',): QueriesFrame(self)}

    def change_frame(self, frame_id):
        for widget in self.winfo_children():
            widget.pack_forget()
        try:
            self.frames[frame_id].pack(fill=tk.BOTH, expand=True)
        except KeyError as error:
            print(f'Unkown frame id: {error}')


class ProductFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('ProductFrame.TFrame', background='red')
        self.config(style='ProductFrame.TFrame')
        label = ttk.Label(self, text='ProductFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


class AFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('AFrame.TFrame', background='Blue')
        self.config(style='AFrame.TFrame')
        label = ttk.Label(self, text='AFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


class BFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('BFrame.TFrame', background='Green')
        self.config(style='BFrame.TFrame')
        label = ttk.Label(self, text='BFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


class CFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('CFrame.TFrame', background='Yellow')
        self.config(style='CFrame.TFrame')
        label = ttk.Label(self, text='CFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


class DFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('DFrame.TFrame', background='Brown')
        self.config(style='DFrame.TFrame')
        label = ttk.Label(self, text='DFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


class ReportsFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('ReportsFrame.TFrame', background='Orange')
        self.config(style='ReportsFrame.TFrame')
        label = ttk.Label(self, text='ReportsFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


class QueriesFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('QueriesFrame.TFrame', background='Pink')
        self.config(style='QueriesFrame.TFrame')
        label = ttk.Label(self, text='QueriesFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


if __name__ == '__main__':
    app = App()
    app.mainloop()
Reply
#4
Thanks Yoriz. This is excellent!
Reply
#5
can someone confirm me that this code does not work? I copied and pasted it into VSC and the frames that should change remain grey. Thanks for you help!


(May-25-2021, 06:48 PM)Yoriz Wrote: Bind an event handler to the treeview event '<<TreeviewSelect>>'
In the event handler change the frame based on the treeview selection.
Here is modified example of your code.
import tkinter as tk
from tkinter import ttk


class App(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title('Test')
        self.iconbitmap()
        self.state('zoomed')
        paned_window = ttk.PanedWindow(self, orient=tk.HORIZONTAL)
        self.tree_view_frame = TreeviewFrame(
            paned_window, width=75, height=300, relief=tk.SUNKEN)
        self.tree_view_frame.tree_view.bind(
            '<<TreeviewSelect>>', self.on_tree_view_select)
        self.display_frame = DisplayFrame(
            paned_window, width=400, height=300, relief=tk.SUNKEN)
        paned_window.add(self.tree_view_frame, weight=0)
        paned_window.add(self.display_frame, weight=4)
        paned_window.pack(fill=tk.BOTH, expand=True)

    def on_tree_view_select(self, event):
        frame_id = self.tree_view_frame.tree_view.selection()
        self.display_frame.change_frame(frame_id)


class TreeviewFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        tree_view = ttk.Treeview(self)
        tree_view.pack()
        tree_view.insert('', '0', 'item1', text='PRODUCT')

        tree_view.insert('item1', '0', 'A', text='A')

        tree_view.insert('item1', '1', 'B', text='B')
        tree_view.insert('item1', '2', 'C', text='C')
        tree_view.insert('item1', '3', 'D', text='D')
        tree_view.insert('', '1', 'item2', text='REPORTS')

        tree_view.insert('', '3', 'item3', text='QUERIES')
        tree_view.config(height=100)
        self.tree_view = tree_view


class DisplayFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # self.config(bg='Red')
        self.frames = {('item1',): ProductFrame(self),
                       ('A',): AFrame(self),
                       ('B',): BFrame(self),
                       ('C',): CFrame(self),
                       ('D',): DFrame(self),
                       ('item2',): ReportsFrame(self),
                       ('item3',): QueriesFrame(self)}

    def change_frame(self, frame_id):
        for widget in self.winfo_children():
            widget.pack_forget()
        try:
            self.frames[frame_id].pack(fill=tk.BOTH, expand=True)
        except KeyError as error:
            print(f'Unkown frame id: {error}')


class ProductFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('ProductFrame.TFrame', background='red')
        self.config(style='ProductFrame.TFrame')
        label = ttk.Label(self, text='ProductFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


class AFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('AFrame.TFrame', background='Blue')
        self.config(style='AFrame.TFrame')
        label = ttk.Label(self, text='AFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


class BFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('BFrame.TFrame', background='Green')
        self.config(style='BFrame.TFrame')
        label = ttk.Label(self, text='BFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


class CFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('CFrame.TFrame', background='Yellow')
        self.config(style='CFrame.TFrame')
        label = ttk.Label(self, text='CFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


class DFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('DFrame.TFrame', background='Brown')
        self.config(style='DFrame.TFrame')
        label = ttk.Label(self, text='DFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


class ReportsFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('ReportsFrame.TFrame', background='Orange')
        self.config(style='ReportsFrame.TFrame')
        label = ttk.Label(self, text='ReportsFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


class QueriesFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        style = ttk.Style(self)
        style.configure('QueriesFrame.TFrame', background='Pink')
        self.config(style='QueriesFrame.TFrame')
        label = ttk.Label(self, text='QueriesFrame')
        label.pack(padx=10, pady=10, anchor=tk.CENTER)


if __name__ == '__main__':
    app = App()
    app.mainloop()
Reply
#6
When I run this I get a panel with two frames. On the left is a frame containing a treeview, on the right a frame that displays a frame selected by the treeview.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] [split] Is there a way to embed a treeview as a row inside another treeview? CyKlop 5 3,360 Oct-20-2021, 12:14 AM
Last Post: CyKlop
  [Tkinter] Scrollbar, Frame and size of Frame Maksim 2 9,007 Sep-30-2019, 07:30 AM
Last Post: Maksim
  [Tkinter] create and insert a new frame on top of another frame atlass218 4 11,122 Apr-18-2019, 05:36 PM
Last Post: atlass218
  [Tkinter] Treeview automatically adjust it's size when pack inside frame Prince_Bhatia 1 27,822 Jul-25-2018, 03:24 AM
Last Post: Larz60+
  [Tkinter] Frame size only works if frame is empty(Solved) Tuck12173 7 6,449 Jan-29-2018, 10:44 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020