9

I'm using a ComboBox as part of a larger GUI, written in python/tkinter.

When the drop-down selection is changed, the color is updated to indicate to the user that something has changed.

However, the combobox also allows the user to type in their own value. I also want the color to change when this happens.

The problem is, I don't see anything in the ComboBox documentation indicating how to do this.

Matt Fenwick
  • 48,199
  • 22
  • 128
  • 192
  • 1
    I guess you'll need a combination of traces and validation to get the exact effect you want. More tricky will be persuading the combobox to like your color changes; style hacking is ill-documented, alas. – Donal Fellows Dec 09 '11 at 03:47
  • @DonalFellows -- true; I could never get any style changes to work until I started using "wrapped" super-widgets that put built-in widgets like comboboxes and checkbuttons in their own frames. Then I can just change the color, or anything else, of the frame. – Matt Fenwick Dec 09 '11 at 14:50

3 Answers3

15

You can use a StringVar as a parameter of the Combobox constructor. This StringVar can be traced (ie, subscribe to each change).

Here a small example:

from Tkinter import *
from ttk import *

def on_field_change(index, value, op):
    print "combobox updated to ", c.get()

root = Tk()
v = StringVar()
v.trace('w',on_field_change)
c = Combobox(root, textvar=v, values=["foo", "bar", "baz"])
c.pack()

mainloop()
FabienAndre
  • 4,514
  • 25
  • 38
7

Just bind '<<ComboboxSelected>>' to a method...

import tkinter as tk
from tkinter import ttk

class Main(tk.Tk):
     
  def __init__(self, *args, **kwargs):
    tk.Tk.__init__(self, *args, **kwargs)
    self.container = tk.Frame(self)
    self.container.pack(side="top", fill = "both", expand=True)
    self.container.grid_rowconfigure(0, weight=1)
    self.container.grid_columnconfigure(0, weight=1)
    self.cb=ttk.Combobox(self.container, values=[0,1, 2, 3] , state='readonly')
    self.cb.bind('<<ComboboxSelected>>', self.modified)    
    self.cb.pack()
                  
  def modified (self, event) :
      print(self.cb.get())
    
main = Main()
main.mainloop()
martineau
  • 119,623
  • 25
  • 170
  • 301
Frank Segers
  • 71
  • 1
  • 1
5

I noticed that somewhere in Python's Tkinter docs, it mentions that Combobox is a subclass of Entry.

With an Entry, here's what you do. Set the configuration:

  • -validatecommand should be set to the thing that you want to happen when a key is pressed (in my case, change a color).
  • -validate should be set to key, meaning that the validation command will be called whenever a key is pressed while the cursor is in the entry.

Here's the tk page on text entries for further reference.

Doing the exact same thing for comboboxes works just the same way (as far as I can tell).

martineau
  • 119,623
  • 25
  • 170
  • 301
Matt Fenwick
  • 48,199
  • 22
  • 128
  • 192