Python Forum
Problems with ValueMember vs DisplayMember with combobox
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Problems with ValueMember vs DisplayMember with combobox
#1
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();
Reply
#2
Please put code in proper tags.
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#3
(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.
Reply
#4
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.
Reply
#5
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()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#6
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.
Reply
#7
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
dford likes this post
Reply
#8
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()
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Problems getting tk Combobox contents to populate properly dford 4 3,878 Jan-08-2022, 02:39 PM
Last Post: dford
  [PyQt] How can I sync Combobox index to other combobox index? nickzsche 2 2,422 Jan-03-2022, 12:29 PM
Last Post: Axel_Erfurt

Forum Jump:

User Panel Messages

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