update of elements in GUI (TKinter)

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Alex1980
    New Member
    • Aug 2010
    • 4

    update of elements in GUI (TKinter)

    hi,
    here's the situation: I'm trying to build a GUI for a Genetic Algorithm that has a number of elements (labels) updated every iteration of the run.

    I've tried doing it in the widget (Label) (1) and in the mainframe (2), but neither worked.

    (1)
    Code:
    Label(mainframe.update_idletasks(),textvariable=best,bg='#321000',fg='#000fff000',font=("Helvetica",x1)).grid(column=1,row=1)
    (2)
    Code:
    mainframe = Frame(root)
    mainframe.grid(column=1000, row=1000, sticky=(N, W, E, S))
    mainframe.columnconfigure(0, weight=1)
    mainframe.rowconfigure(0, weight=1)
    mainframe.update()
    Thanks for any ideas
  • dwblas
    Recognized Expert Contributor
    • May 2008
    • 626

    #2
    You use a Tkinter variable since they are different from a Python variable, set() the new value (which converts to a Tkinter variable), and update the widget. The following updates a counter every second and displays it on the screen. If this does not solve the problem, post back with more detail (but thanks for not posting the thousands of lines of code for the Genetic Algorithm ). Note that update is considered by some to be bad coding style and you should call some event. But sometimes using mutiprocessing or threading isn't a better choice .
    Code:
    import time
    from Tkinter import *
    
    root = Tk()
    root.geometry('100x50+20+20')
    
    mainframe = Frame(root)
    mainframe.grid(column=1000, row=1000, sticky=(N, W, E, S))
    mainframe.columnconfigure(0, weight=1)
    mainframe.rowconfigure(0, weight=1)
    
    best = StringVar()
    best.set('start')
    x1 = 12
    Label(mainframe,textvariable=best,bg='#321000',fg='#000fff000',font=("Helvetica",x1)).grid(column=1,row=1)
    
    for x in range(10):
        time.sleep(1.0)
        best.set('test # %d' % (x))
        mainframe.update()
    root.mainloop()

    Comment

    • bvdet
      Recognized Expert Specialist
      • Oct 2006
      • 2851

      #3
      StringVar() best can be updated using StringVar() method set(). Any widget whose textvariable option is slaved to this variable will be updated when the main loop next idles.

      Comment

      • bvdet
        Recognized Expert Specialist
        • Oct 2006
        • 2851

        #4
        You can get away from the update() method by using after(). Following is dwblas example, modified for after():
        Code:
        from Tkinter import *
        
        root = Tk()
        root.geometry('100x50+20+20')
         
        mainframe = Frame(root)
        mainframe.grid(column=1000, row=1000, sticky=(N, W, E, S))
        mainframe.columnconfigure(0, weight=1)
        mainframe.rowconfigure(0, weight=1)
         
        best = StringVar()
        best.set('start')
        x1 = 12
        label1 = Label(mainframe,textvariable=best,bg='#321000',fg='#000fff000',font=("Helvetica",x1))
        label1.grid()
        
        def run(n, master):
            best.set('test # %d' % (n))
            n += 1
            if n <= 10:
                mainframe.after(1000, run, n, master)
        
        run(0, mainframe)
        root.mainloop()

        Comment

        • Alex1980
          New Member
          • Aug 2010
          • 4

          #5
          hey thanks this seems to work...one more question, if u don't maind, what if I'd like to launch this counter at a click of a button? I've tried modifying your code

          Code:
          from Tkinter import *
           
          root = Tk()
          root.geometry('100x50+20+20')
           
          mainframe = Frame(root)
          mainframe.grid(column=1000, row=1000, sticky=(N, W, E, S))
          mainframe.columnconfigure(0, weight=1)
          mainframe.rowconfigure(0, weight=1)
           
          best = StringVar()
          best.set('start')
          x1 = 12
          label1 = Label(mainframe,textvariable=best,bg='#321000',fg='#000fff000',font=("Helvetica",x1))
          label1.grid()
           
          def run(*args):
              n=0;master=mainframe
              best.set('test # %d' % (n))
              n += 1
              if n <= 10:
                  mainframe.after(1000, run, n, master)
          
          but1=Button(text="RUN",command=run)
          bu1.grid() 
          run(0, mainframe)
          root.mainloop()
          but apparently it didn't work out. Sorry, I;m very new to both Python and GUI. The algorithm without this iterative update trick works just fine.
          Last edited by bvdet; Aug 19 '10, 12:19 AM. Reason: Fixed code tags [code]....[/code]

          Comment

          • bvdet
            Recognized Expert Specialist
            • Oct 2006
            • 2851

            #6
            A little modification:
            Code:
            from Tkinter import *
            
            font1 = ("Helvetica",12)
            
            root = Tk()
            root.geometry('100x50+20+20')
             
            mainframe = Frame(root)
            mainframe.grid(column=1000, row=1000, sticky=(N, W, E, S))
            mainframe.columnconfigure(0, weight=1)
            mainframe.rowconfigure(0, weight=1)
             
            best = StringVar()
            best.set('start')
            label1 = Label(mainframe,textvariable=best,bg='#321000',fg='#000fff000',font=font1)
            label1.grid()
             
            def run(n=0, master=mainframe):
                best.set('test # %d' % (n))
                n += 1
                if n <= 10:
                    mainframe.after(1000, run, n, master)
            
            but1=Button(text="RUN",command=run)
            but1.grid()
            root.mainloop()

            Comment

            • Alex1980
              New Member
              • Aug 2010
              • 4

              #7
              OK thanx a great lot, this actually did work, but there seems to be a bit of a problem: the function [run] is called every time from scratch, i.e. if I update an array (pretty much how a genetic algorithm works) I need to store it for the next iteration to use. Is this somehow doable in this case?

              I see that you start with n=0 and then add an increment every iteration until some condition is fulfilled, so each time [run] is called n is not defaulted to 0, so this should work with arrays too...

              Sorry for this being messy, but I've written the algorithm some time ago and this is the only thing that doesn't work and gets me concerned.

              thanks again!

              Comment

              • Alex1980
                New Member
                • Aug 2010
                • 4

                #8
                Sorry for this, I actually sorted the way out)

                thnx 2 everyone

                Comment

                Working...