Joe Michail
Joe Michail

Reputation: 449

Labels Aren't Changing

I'm only going to post a snippet of my code, because essentially, it does the same thing.

string = ''

time_calc = Tk()
time_calc.geometry('500x400')
time_calc.title("Calculate A Time")
time_calc_frame= Frame(time_calc).grid(row=0, column=0)

jul_box = Entry(time_calc)
jul_box.insert(0, "Julian Date")
jul_box.pack(side = TOP)
jul_box.bind('<Return>')

def jd2gd(jd):
  global string
  jd=jd+0.5
  Z=int(jd)
  F=jd-Z
  alpha=int((Z-1867216.25)/36524.25)
  A=Z + 1 + alpha - int(alpha/4)

  B = A + 1524
  C = int( (B-122.1)/365.25)
  D = int( 365.25*C )
  E = int( (B-D)/30.6001 )

  dd = B - D - int(30.6001*E) + F

  if E<13.5:
            mm=E-1

  if E>13.5:
            mm=E-13

  if mm>2.5:
            yyyy=C-4716

  if mm<2.5:
            yyyy=C-4715

  months=["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
  daylist=[31,28,31,30,31,30,31,31,30,31,30,31]
  daylist2=[31,29,31,30,31,30,31,31,30,31,30,31]

  h=int((dd-int(dd))*24)
  min =int((((dd-int(dd))*24)-h)*60)
  sec=86400*(dd-int(dd))-h*3600-min*60

  # Now calculate the fractional year. Do we have a leap year?
  if (yyyy%4 != 0):
            days=daylist2
  elif (yyyy%400 == 0):
            days=daylist2
  elif (yyyy%100 == 0):
            days=daylist
  else:
            days=daylist2

  hh = 24.0*(dd % 1.0)
  min = 60.0*(hh % 1.0)
  sec = 60.0*(min % 1.0)

  dd =  dd-(dd%1.0)
  hh =  hh-(hh%1.0)
  min =  min-(min%1.0)

  if hh < 10:
    hh = '0%s'%str(int(hh))
  else:
      hh = int(hh)
  if min < 10:
    min = '0%s'%str(int(min))
  else:
      min = int(min)
  if sec < 10:
    sec = '0%s'%str(int(sec))
  else:
      sec = int(sec)

  string = "%s/%s/%s  %s:%s:%s UTC" % (str(int(mm)), str(int(dd)), str(yyyy), str(hh),               str(min), str(sec))
  print string
  return


def j2ghandler():
  jul = float(jul_box.get())

  jd2gd(jul)

j2g_button = Button(time_calc, text='Convert Julian\n to Gregorian', command = j2ghandler, width= 25, pady=5).pack(side=TOP)

#Draw Time String on Canvas
var = StringVar()
var.set(string)
label = Label(time_calc, textvariable=var)
label.pack(side=TOP)

I know, "snippet". What should happen when you put in the number and click the button is it should, and does, change the string "string" behind the scenes. I can't get the label to update though. I've tried, as you can see, to use StringVar() to update the label. Also, I tried doing an .update() on end of the function but it didn't work.

Any help towards this matter would be greatly appreciated. This is the only part of the application that no matter what I try, I can't get it to work.

Thanks for the help.

PS I didn't include all that from Tkinter import *, it's redundant and not necessary for this code.

Upvotes: 2

Views: 99

Answers (3)

user2555451
user2555451

Reputation:

The parts in the comment boxes are what I changed:

#####################
from Tkinter import *
#####################
string = ''

time_calc = Tk()
time_calc.geometry('500x400')
time_calc.title("Calculate A Time")
time_calc_frame= Frame(time_calc).grid(row=0, column=0)

jul_box = Entry(time_calc)
jul_box.insert(0, "Julian Date")
jul_box.pack(side = TOP)
jul_box.bind('<Return>')

def jd2gd(jd):
  global string
  jd=jd+0.5
  Z=int(jd)
  F=jd-Z
  alpha=int((Z-1867216.25)/36524.25)
  A=Z + 1 + alpha - int(alpha/4)

  B = A + 1524
  C = int( (B-122.1)/365.25)
  D = int( 365.25*C )
  E = int( (B-D)/30.6001 )

  dd = B - D - int(30.6001*E) + F

  if E<13.5:
            mm=E-1

  if E>13.5:
            mm=E-13

  if mm>2.5:
            yyyy=C-4716

  if mm<2.5:
            yyyy=C-4715

  months=["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
  daylist=[31,28,31,30,31,30,31,31,30,31,30,31]
  daylist2=[31,29,31,30,31,30,31,31,30,31,30,31]

  h=int((dd-int(dd))*24)
  min =int((((dd-int(dd))*24)-h)*60)
  sec=86400*(dd-int(dd))-h*3600-min*60

  # Now calculate the fractional year. Do we have a leap year?
  if (yyyy%4 != 0):
            days=daylist2
  elif (yyyy%400 == 0):
            days=daylist2
  elif (yyyy%100 == 0):
            days=daylist
  else:
            days=daylist2

  hh = 24.0*(dd % 1.0)
  min = 60.0*(hh % 1.0)
  sec = 60.0*(min % 1.0)

  dd =  dd-(dd%1.0)
  hh =  hh-(hh%1.0)
  min =  min-(min%1.0)

  if hh < 10:
    hh = '0%s'%str(int(hh))
  else:
      hh = int(hh)
  if min < 10:
    min = '0%s'%str(int(min))
  else:
      min = int(min)
  if sec < 10:
    sec = '0%s'%str(int(sec))
  else:
      sec = int(sec)

  string = "%s/%s/%s  %s:%s:%s UTC" % (str(int(mm)), str(int(dd)), str(yyyy), str(hh),               str(min), str(sec))
  print string
  ##############
  return string
  ##############


def j2ghandler():
  jul = float(jul_box.get())

  #####################
  var.set(jd2gd(jul))
  #####################

j2g_button = Button(time_calc, text='Convert Julian\n to Gregorian', command = j2ghandler, width= 25, pady=5).pack(side=TOP)

#Draw Time String on Canvas
var = StringVar()
var.set(string)
label = Label(time_calc, textvariable=var)
label.pack(side=TOP)

##############################
time_calc.mainloop()
##############################

Basically, the key was to make jd2gd return string and then use that to update the label variable.

Upvotes: 1

Daniel Sawka
Daniel Sawka

Reputation: 1380

You need to remember that this GUI module (like almost all) is event-driven, what means functions are called whenever some event occurs (button clicked, etc.) and this is all made by mainloop of Tkinter.

In your case: past your definition code (all that time_calc = Tk() and on) you start loop; then, when event of button clicked fires, it leads to call of binded function (j2ghandler()). From now application waits for it to return, and goes back to its loop.

Solution

I assume you wanted to change text of label that's below button, when it's pushed (time gets converted).

You need to set label's value in event-called function; here, after printing:

def jd2gd(jd):
    #global string
    ...
    print string
    var.set(string)
    #return

Note: Commented lines are not needed.

Label gets changed without must of recreating Label object. Also Al.Sal tip on globals is important here. Request functions should never save state.

Good luck with Python!

Upvotes: 1

Al.Sal
Al.Sal

Reputation: 984

I would stray away from using global, especially with string as it is ambiguous.

Have jd2gd return string (or whatever new name you decide to give it) and at the bottom of your program and include the code in j2ghandler. For example:

def j2ghandler():
    jul = float(jul_box.get())
    gregDate = jd2gd(jul)
    label = Label(time_calc, text=gregDate)
    label.pack(side=TOP)

You then remove the last 4 lines.

I haven't tested this so if there is an error, one solution would be to change the button to:

j2g_button = Button(time_calc, text='Convert Julian\n to Gregorian', command=lambda: j2ghandler(time_calc), width= 25, pady=5)
j2g_button.pack(side=TOP)

and j2ghandler to:

def j2ghandler(master):
    jul = float(jul_box.get())
    gregDate = jd2gd(jul)
    label = Label(master, text=gregDate)
    label.pack(side=TOP)

By the way... You might want to change:

j2g_button = Button(time_calc, text='Convert Julian\n to Gregorian', command = j2ghandler, width= 25, pady=5).pack(side=TOP)

to:

j2g_button = Button(time_calc, text='Convert Julian\n to Gregorian', command = j2ghandler, width= 25, pady=5)
j2g_button.pack(side=TOP)

It works as it is but if you try to use j2g_button again it will return a none object.

Good luck!

Upvotes: 0

Related Questions