Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
421 views
in Technique[技术] by (71.8m points)

python - tkinter Treeview Bind with Arguments

I am writing a personal finance application in Python using a SQLite3 database and tkinter as my GUI generator. For brevity, I am just including the problematic block of code:

import tkinter as tk
import tkinter.ttk as ttk
import sqlite3

def select_item(event):
    db_name = 'portfolio.db'
    db_conn = sqlite3.connect(db_name)
    db_cursor = db_conn.cursor()
    # get information from currently selected Account in tree
    tree_item_id = accts_tree.focus()
    tree_item = accts_tree.item(tree_item_id)
    # get Account ID from record selected in Treeview
    accts_acctID = tree_item['values'][0]    # save Account ID for selected Account in tree
    # get Account information from database for selected Account ID
    db_cursor.execute('''SELECT acct_id, acct_name FROM accounts WHERE acct_id = ''' +
      str(accts_acctID) + ";")
    db_result = db_cursor.fetchone()
    # db_result[0] is the Account ID
    # db_result[1] is the Account Name
    accts_name.set(db_result[1])
    db_conn.close()    # close the connection to the database

def createAccountsPage(topicPage_frame, topicPages, graphics_path, db_name):
    # create main frame for containing both the frame for the Accounts tree view and the frame
    # for displaying specific Account information
    accts_frame = tk.Frame(topicPage_frame, width=1810, height=960)
    accts_frame.place(x=0, y=0)
    # create a top frame inside main Frame for displaying Accounts tree view
    accts_tree_frame = tk.Frame(accts_frame, width=1516, height=630)
    accts_tree_frame.place(x=156, y=90)
    accts_tree_frame.pack_propagate(0)
    # create Accounts tree view widget
    accts_columns = ['id', 'Name']
    accts_tree_style = ttk.Style()
    accts_tree_style.configure('mystyle.Treeview', font=('Times', 14))
    accts_tree = ttk.Treeview(accts_tree_frame, selectmode='browse', columns=accts_columns,
      style='mystyle.Treeview', show='tree')
    accts_tree.pack(fill='y', side='left')
    # create label for the Account Name column directly above the Accounts tree view
    accts_tree_name_lbl = tk.Label(accts_frame, text='Name')
    accts_tree_name_lbl.place(x=401, y=65)
    accts_tree.tag_configure('TreeFont', font=('Times', '14'))
    accts_tree.column('id', width=40)
    accts_tree.heading('id', text=' ID', anchor='w')
    accts_tree.column('Name', width=564)
    accts_tree.heading('Name', text=' Name', anchor='w')
    # Level 1 of tree = Assets
    accts_tree_assets = accts_tree.insert('', 1, 1000, text='Assets', values=('', ''),
      tags='TreeFont')
    accts_tree_liabilities = accts_tree.insert('', 1, 1001, text='Liabilities', values=('', ''),
      tags='TreeFont')
    # load all defined Accounts from 'accounts' table of SQLite3 database into a list
    db_conn = sqlite3.connect(db_name)
    db_cursor = db_conn.cursor()
    db_cursor.execute('''SELECT acct_id, acct_name FROM accounts ORDER BY acct__name;''')
    accts_data = db_cursor.fetchall()
    db_conn.close()    # close the connection to the database
    # display all Accounts in the 'Assets' or 'Liabilities' (whichever is applicable)
    for acct_record in accts_data:
        if acct_record[1] == 'Asset':
            accts_tree.insert(accts_tree_assets, 'end', values=acct_record, tags='TreeFont')
        else:
            accts_tree.insert(accts_tree_liabilities, 'end', values=acct_record, tags='TreeFont')
    # create lower frame for displaying information from selected Account
    accts_acct_frame = tk.Frame(accts_frame, width=1516, height=215, bg='floral white')
    accts_acct_frame.place(x=156, y=735)
    accts_acctID_lbl = tk.Label(accts_acct_frame, text='Acct ID:', anchor='e', width=8)
    accts_acctID_lbl.place(x=1334, y=10)
    accts_acctID = tk.StringVar()
    accts_acctID.set('')
    accts_acctID_ent = tk.Entry(accts_acct_frame, textvariable=accts_acctID, width=10)
    accts_acctID_ent.place(x=1414, y=10)
    # add Label and Entry widgets in the lower frame for the Account Name field
    accts_acctname_lbl = tk.Label(accts_acct_frame, text='Account Name:', anchor='e', width=14)
    accts_acctname_lbl.place(x=5, y=90)
    accts_name = tk.StringVar()
    accts_name.set('')
    accts_acctname_ent = tk.Entry(accts_acct_frame, textvariable=accts_name, width=40)
    accts_acctname_ent.place(x=140, y=90)
    # bind <Key Release> event on Accounts tree to react to when user selects an Account in the tree
    accts_tree.bind('<ButtonRelease-1>', select_item)

The last line is where I bind the button release to the tree view such that, when a displayed in the Account tree view is selected, it does a callback to select_item(). In order for select_item() to work properly, I must pass the values for db_name, accts_tree, accts_acctID, and accts_name from createAccountsPage(). This has proven to be quite a challenge. I have tried using lambda in the bind statement, but with no success. The only thing that has worked is that I made these variables GLOBAL inside createAccountsPage(); I am afraid, however, that this will cause problems later with other functions & methods. I really do just want to pass the values to select_item() from createAccountsPage() whenever a different Account entry is selected from the tree view.

Also, I tried, without success, to pass db_conn and db_cursor from the method that calls createAccountsPage() and then to pass them again to select_item() to avoid having to open a connection, get data from the database, then immediately close the database again - over and over again. I was able do this (albeit how I did it is not shown in the code below) as far as into createAccountsPage(), but it fell apart when I tried to pass these two SQLite3-related values into select_item(). This is why you see me opening and closing the sqlite3 connection repeatedly.

Any help will be most appreciated.

Thank you in advance.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...