Search code examples
pythontkinterdisabled-input

Tkinter update state (disable): need for redraw/refresh?


I cannot get the state of a (tk.)Label and (tk.)Checkbutton to visually turn to disable and normal depending on the value of an OptionMenu.

The command binding on the OptionMenu below seems fine, but my use of configure(state=...), in updateState() has no visible effect. Should I force some "refresh" or "repaint" (if yes how in the partial code below?) or am I missing something else?

import Tkinter
from Tkinter import Frame, LabelFrame, Label, Entry, Button, StringVar, OptionMenu, Checkbutton, IntVar, DISABLED, NORMAL

class GeneratorDialog:

  # The UI to configure the settings by the user
  def __init__(self, root, ctrl):
    self.__root = root
    self.__ctrl = ctrl

  def updateState(self, value, label, entry):
    if(value.get()==CONST.FORMAT_PDF): # test works, as the dialog below show in alternance as expected
        tkMessageBox.showinfo('Info', message="enabling checkbox")
        label.configure(state=NORMAL)
        entry.configure(state=NORMAL)
    else:            
        tkMessageBox.showinfo('Info', message="disabling the checkbox")
        label.configure(state=DISABLED)
        entry.configure(state=DISABLED)
    #self.__root.update_idletasks() # how to force "redraw" with grid() manager?


  def show(self):
    self.__root.title(CONST.APP_NAME)
    mainFrame = Frame(self.__root)
    mainFrame.grid(sticky='ew')
    outputFrame = LabelFrame(mainFrame, text='Output Settings')
    outputFrame.grid(column=0, row=1, padx=5, pady=5, sticky='ew')


    keepGeneratedScribusFilesLabel = Label(outputFrame, text='Keep Scribus Files:', width=15, anchor='e')
    keepGeneratedScribusFilesLabel.grid(column=4, row=2, padx=5, pady=5, sticky='e')
    keepGeneratedScribusFilesCheckbox = Checkbutton(outputFrame, variable=self.__ctrl.getKeepGeneratedScribusFilesCheckboxVariable(), anchor='w')
    keepGeneratedScribusFilesCheckbox.grid(column=5, row=2, padx=5, pady=5, sticky='w')

    mergeOutputLabel = Label(outputFrame, text='Merge in Single File:', width=15, anchor='w')
    mergeOutputLabel.grid(column=0, row=2, padx=5, pady=5, sticky='w')
    mergeOutputCheckbox = Checkbutton(outputFrame, variable=self.__ctrl.getMergeOutputCheckboxVariable())
    mergeOutputCheckbox.grid(column=1, row=2, padx=5, pady=5, sticky='w')  

    outputFormatLabel = Label(outputFrame, text='Output Format:', anchor='e')
    outputFormatLabel.grid(column=2, row=2, padx=5, pady=5, sticky='e')
    outputFormatListBox = OptionMenu(outputFrame, self.__ctrl.getSelectedOutputFormat(), *self.__ctrl.getOutputFormatList(),
        command=lambda l=keepGeneratedScribusFilesLabel, c=keepGeneratedScribusFilesCheckbox, v=self.__ctrl.getSelectedOutputFormat(): self.updateState(v, l, c))
    outputFormatListBox.grid(column=3, row=2, padx=5, pady=5, sticky='w')            


    # Buttons to Cancel or to Run the Generator with the given Settings
    helpButton = Button(buttonFrame, text='Help', width=10, command=self.__ctrl.helpButtonHandler)
    helpButton.grid(column=0, row=0, padx=5, pady=5, sticky='e')
    cancelButton = Button(buttonFrame, text='Cancel', width=10, command=self.__ctrl.buttonCancelHandler)
    cancelButton.grid(column=1, row=0, padx=5, pady=5, sticky='e')
    generateButton = Button(buttonFrame, text='Generate', width=10, command=self.__ctrl.buttonOkHandler)
    generateButton.grid(column=2, row=0, padx=5, pady=5, sticky='e')

    # Finally show the Generator Dialog
    mainFrame.grid()
    self.__root.grid()
    self.__root.mainloop()

full code is at https://github.com/berteh/ScribusGenerator/blob/93a12de4be28054344533ad8fc424e37180668de/ScribusGenerator.py#L278


Solution

  • solved it by using class variables (self.X) instead of lambda local variables.

    still don't know why the former code (with local variables in the lambda) would not update the status of the Tk elements (maybe it created copies thereof?)... but I found a workaround.

    thanks all for your help