How can I dynamically update ttk.combobox?

我的梦境 提交于 2021-02-10 13:24:08

问题


I am creating a GUI using Python 3.4 and Tkinter on a Windows 8 computer.

The GUI has some Entry inputs at the top, then some comboboxes. I want the combobox to acquire a list of options from a text file that is described by the previous inputs (file name, the row in which the requisite information is found, delimiter type, etc.). I am trying to use the postcommand, but it seems to run first thing and never update, rather then update every time I access the drop down menu of the combobox.

    datatypes = []
    datatypes = ttk.Combobox(tab_loc, textvariable=std1, values=datatypes, postcommand=self.get_datatypes(datatypes,
           self.flnm2.get(), self.hl2_text.get(), self.delim2.get(), self.fcd2_text.get())).grid(pady=v_pad,
           padx=h_pad, row=8, column=1, sticky=EW)

    def get_datatypes(self, lst, flnm, hl, delim, fcd):
        # Problem: postcommand runs at start of GUI. Prevents updating.
        lst += ["test", "worked?"]
        print("stuff")
        lst += flnm
        lst += hl
        try:
            # open the file, get the line, break it apart.
        except:
            pass

self.flnm2, self.hl2_text, self.delim2, and self.fcd2_text are some of the previous inputs. They are StringVar.

When I run this code, the combobox has the options test, worked?, and two blank lines (presumably for flnm and hl). I plan to have multiple comboboxes like this, just with different inputs, so I need a function I can give inputs to and then updates datatypes.

What am I doing wrong?


回答1:


You are calling self.get_datatypes(...) and assigning the result to the postcommand attribute at the time you create the combobox. That is why it runs exactly once: you told it to. Just like with command attributes, you must give a reference to a function when definining the postcommand attribute.

Create a method specifically for the post command for each combobox, use a reference to that for your postcommand, and then call get_datatypes from that function after fetching the values from the other widgets.

It should look something like this:

datatypes = ttk.Combobox(..., postcommand=self.combo_post_command, ...)
...
def combo_post_command(self):
    flnm2 = self.flnm2.get()
    hl2_text = self.hl2_text.get()
    delim2 = self.delim2.get()
    fcd2_text = self.fcd2_text.get()
    return self.get_datatypes(datatypes, flnm2, hl2_text, delim2, fcd2_text)

I'm not exactly sure what datatypes is supposed to be. You define it as an empty list, then reset it to be the widget itself. Regardless, this shows the general concept.

It may seem like you have a lot of duplicated code by having a function for each combobox, but you have to call all the get() functions somewhere. You either try to cram that all into the configuration of the widget, or you put it in a function. Putting it in the function is more explicit, and easier to debug and maintain over time.




回答2:


You can finish your homework with a simple lambda function.

valuetypes = ["bla1", "bla2", "bla3"]
datatypes = ttk.Combobox(..., values=valuetypes, 
                          postcommand=lambda: datatypes.configure(values=valuetypes), ...) 

valuetypes.append["another bla"] 

When you click on the down-arrow of the Combobox, the changes will appear in the drop-down menu.



来源:https://stackoverflow.com/questions/32385771/how-can-i-dynamically-update-ttk-combobox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!