Posts: 18
Threads: 5
Joined: Jan 2022
Feb-23-2022, 02:10 PM
(This post was last modified: Feb-23-2022, 02:32 PM by dford.)
I might have included more code than necessary. The code in question is the last four lines.
What I get in the display is a concatenation of InspectorID and LName. What I get as the value (as determined by a print statement) is the same thing.
I would like to display the name and store the InspectorID into the database table.
How do I sort out the combobox so it performs correctly?
Thanks.
Here is a subset of my code:
lblInspector = Label(maininset, text="Inspector", bg="lightgray", width=lblWidth).place(x=col3, y=rowspacer*4)
cmbInspector = ttk.Combobox(maininset)
cmbInspector.configure(textvariable=Inspector)
cmbInspector.delete(0,END)
#gets current InspectorID from Projects table
cmbInspector.insert(0,getFld(0,'InspectorID'))
cmbInspector.place(x=col4, y= rowspacer*4)
Inspector.trace_add("write", flagSave)
#dataframe for Inspectors combobox
insp_df=pd.read_sql('select InspectorID, LName from Inspectors', conn)
#create Inspector combobox
cmbInspector.ValueMember = "InspectorID";
cmbInspector.DisplayMember = "LName";
cmbInspector['values']= insp_df.values.tolist();
Posts: 1,145
Threads: 114
Joined: Sep 2019
Please put code in proper tags.
Posts: 18
Threads: 5
Joined: Jan 2022
(Feb-23-2022, 02:14 PM)menator01 Wrote: Please put code in proper tags.
Done. Sorry. Mind is stuck inside trying to figure out this problem.
Posts: 18
Threads: 5
Joined: Jan 2022
Please ignore this thread. I tried to delete it but can't. I found a previous thread by me from a couple of months ago there I seemingly solved the problem.
My apologies for this. I'm old and my memory sucks.
Posts: 1,145
Threads: 114
Joined: Sep 2019
In any case I have an example of what I think you were trying to do.
Load a combobox from a pandas dataframe.
import tkinter as tk
from tkinter import ttk
import pandas as pd
data = {
'id': [0,1,2,3],
'name': ['john', 'ralph', 'tammy', 'sue']
}
df = pd.DataFrame(data)
root = tk.Tk()
root.geometry('200x100+250+250')
root['pady']=10
var = tk.StringVar()
cmb = ttk.Combobox(root, textvariable=var, values=df['name'].to_string(index=False, header=False))
cmb.current(0)
cmb.pack()
root.mainloop()
Posts: 18
Threads: 5
Joined: Jan 2022
Thanks. I still need to figure out how to get the 'id' portion out. This is sending out the 'name' portion of the id/name structure.
Posts: 6,783
Threads: 20
Joined: Feb 2020
Subclass combobox and have your version call the command using the id instead of the name.
Write a shim that is called by the combobox. The shim looks up the id by name and calls a function using the id
Posts: 6,783
Threads: 20
Joined: Feb 2020
import tkinter as tk
from tkinter import ttk
class DictionaryBox(ttk.Combobox):
"""Combobox that takes a dictionary as values"""
def __init__(self, *args, **kwargs):
values = kwargs.pop("values") if "values" in kwargs else None
super().__init__(*args, **kwargs)
self._set_values(values)
def confg(self, **kwargs):
"""Intercept .cofigure(values=)"""
if "values" in kwargs:
self._set_values(kwargs.pop("values"))
super().config(**kwargs)
def __setitem__(self, attr, value):
"""Intercept ["values"] ="""
if attr == "values":
self._set_values(value)
else:
super().__setitem__(attr, value)
def _set_values(self, values):
"""Set the values dictionary. Keys appear as options in the combobox"""
self._values = values
if values:
self._reverse = {value:key for key, value in values.items()}
super().config(values=list(values.keys()))
else:
self._reverse = {}
super().config(values=None)
def value(self):
"""Return value associated with selection"""
return self._values[self.get()]
def set(self, value):
"""Set current value using key or value"""
if value not in self._values and value in self._reverse:
value = self._reverse[value]
super().set(value)
class MainWindow(tk.Tk):
"""Root window class"""
def __init__(self, *args, title=None, **kwargs):
super().__init__(*args, **kwargs)
if title:
self.title(title)
self.name = tk.StringVar()
tk.Label(self, text="Name").grid(row=0, column=0, padx=5, pady=5)
tk.Label(self, textvariable=self.name).grid(row=0, column=1, padx=5, pady=5)
self.value = tk.StringVar()
tk.Label(self, text="Value").grid(row=1, column=0, padx=5, pady=5)
tk.Label(self, textvariable=self.value).grid(row=1, column=1, padx=5, pady=5)
tk.Label(self, text = "Numbers").grid(row=2, column=0, padx=5, pady=5)
self.db = DictionaryBox(self, values={"One":1, "Two":2, "Three":3})
self.db.grid(row=2, column=1, padx=5, pady=5)
self.db.bind("<<ComboboxSelected>>", self.change)
tk.Button(self, text='One', width=15, command=lambda: self.db.set("One")) \
.grid(row=3, column=0, padx=5, pady=5)
tk.Button(self, text='1', width=15, command=lambda: self.db.set(1)) \
.grid(row=3, column=1, padx=5, pady=5)
tk.Button(self, text='Two', width=15, command=lambda: self.db.set("Two")) \
.grid(row=4, column=0, padx=5, pady=5)
tk.Button(self, text='2', width=15, command=lambda: self.db.set(2)) \
.grid(row=4, column=1, padx=5, pady=5)
def change(self, _):
self.name.set(self.db.get())
self.value.set(self.db.value())
def main():
app = MainWindow(title="Combobox Example")
app.mainloop()
if __name__ == '__main__':
main()
|