0

I have several treeview tables.

After some moment I need to apply some property to all tables. All tables are combined in dictionary, for example:

all_trees = {1: some_tree, 2: one_more_tree, 3: another_tree}

When the moment appears I need to make this type of operation to change one property in all tables:

for key in all_trees.keys():
    tree = all_trees[key]
    tree.bind("<Button-3>", lambda event: new_property(event, tree))

New property makes appearing text 'hello' after right click mouse to the row in table. After executing this operation only the last table has the new property.

What's the problem? Why this property is not applied to all tables? P.S: i need to make my project using python2.7, so all my code is written using old version of python

Below is a full code:

import Tkinter as tk
from ttk import Treeview, Frame
from Tkinter import Menu, LEFT, NO, YES


data_for_tables = {1: 'one', 2: 'two', 3: 'three'} 
list_of_tables = [1, 2, 3]

root = tk.Tk()
frame = tk.Frame(root)
frame.pack()

def make_tree(frame):
    """creating Treeview table"""

    tree = Treeview(frame)
    tree["columns"] = ("one", "two", "three")
    tree.heading("#0", text="")
    tree.column("#0", minwidth=0, width=5, stretch=NO)
    tree.heading("one", text="Port")
    tree.column("one", minwidth=0, width=30, stretch=NO)
    tree.column("two", minwidth=0, width=60, stretch=NO)
    tree.heading("three", text="State")
    tree.column("three", minwidth=0, width=60, stretch=YES)
    tree['height'] = 3
    tree.pack(side=LEFT)
    return tree

def insert_value(info, tree):
    """Inserting values to Treeview table"""

    for key in info.keys():
        tree.insert("", "end", values=(str(key), info[key], "<><><>"))

def new_property(event, tree):
    """after right ckick mouse appears text 'hello' in console"""

    row_id = tree.identify_row(event.y)
    if row_id:
        print('hello')


global all_trees
for num in list_of_tables:
    all_trees = {num: make_tree(frame)}
    for key in all_trees.keys():
        tree = all_trees[key]
        insert_value(data_for_tables, tree)

for key in all_trees.keys():
    tree = all_trees[key]
    tree.bind("<Button-3>", lambda event: new_property(event, tree))

root.mainloop()
2
  • After doing tree = all_trees.keys(), have you examined tree to see if it's what you think it is? I'm guessing it's not what you think it is. Commented May 14, 2021 at 2:09
  • The second posted code does not match with that in the full code. Commented May 14, 2021 at 2:13

1 Answer 1

1

There are few issues in your code:

global all_trees   # <-- not necessary
for num in list_of_tables:
    all_trees = {num: make_tree(frame)} # <-- reset all_trees
    # below for loop is not necessary
    for key in all_trees.keys():
        tree = all_trees[key]
        insert_value(data_for_tables, tree)
# at here, all_trees has only the last item created in the above for loop

for key in all_trees.keys():
    tree = all_trees[key]
    tree.bind("<Button-3>", lambda event: new_property(event, tree))
    #                                                          ^
    # 'tree' used inside lambda will be always the last 'tree' after the for loop
    # actually this argument is not necessary

Below is sample how to fix the above issues:

def new_property(event):
    tree = event.widget
    row_id = tree.identify_row(event.y)
    if row_id:
        print('hello', tree, row_id)

all_trees = {num: make_tree(frame) for num in list_of_tables}
for tree in all_trees.values():
    insert_value(data_for_tables, tree)
    tree.bind("<Button-3>", new_property)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.