IntVar returning only 0 even with .get() function

╄→尐↘猪︶ㄣ 提交于 2019-12-08 11:48:34

问题



This is a population model so the entries must be integers to be used for calculation.

import sys
import tkinter
from tkinter import*
import time

global v


global popJ
popJ = 0

def genInput(): #Allows the user to input the data

    gen = Tk()
    gen.wm_title("Data Input")
    v = IntVar()
    ent1 = Entry(gen, textvariable = v).pack()
    ent1Txt = Label(gen, text = 'Input Juvenile Populations')

    ent1Txt.pack()


    v2 = StringVar()
    ent2 = Entry(gen, textvariable = v2)
    ent2Txt = Label(gen, text = 'Input Adult Populations')
    ent2.pack()
    ent2Txt.pack()

    v3 = StringVar()
    ent3 = Entry(gen, textvariable = v3)
    ent3Txt = Label(gen, text = 'Input Senile Populations')
    ent3.pack()
    ent3Txt.pack()

    v4 = StringVar()
    ent4 = Entry(gen, textvariable = v4)
    ent4Txt = Label(gen, text = 'Input Survival rates for Juveniles')
    ent4.pack()
    ent4Txt.pack()

    v5 = StringVar()
    ent5 = Entry(gen, textvariable = v5)
    ent5Txt = Label(gen, text = 'Input Survival rates for Adults')
    ent5.pack()
    ent5Txt.pack()

    v6 = StringVar()
    ent6 = Entry(gen, textvariable = v6)
    ent6Txt = Label(gen, text = 'Input Survival rates for Seniles')
    ent6.pack()
    ent6Txt.pack()

    v7 = StringVar()
    ent7 = Entry(gen, textvariable = v7)
    ent7Txt = Label(gen, text = 'Input the birth rate')
    ent7.pack()
    ent7Txt.pack()

    v8 = StringVar()
    ent8 = Entry(gen, textvariable = v8)
    ent8Txt = Label(gen, text = 'Number of Generations')
    ent8.pack()
    ent8Txt.pack()

    def quit1():   # Need to be here or it breaks the program
        gen.destroy()            
        return
    def submit():
        popJ = v.get()
        popJtxt = Label(gen, text= v.get()).pack()
        return



    submit1= Button(gen, text="Submit")
    submit1.pack()
    submit1.configure(command = submit)
    return1 = Button(gen, text = 'Return to Menu')
    return1.pack(pady=30)
    return1.configure(command = quit1)    
    return
def genView(): # should display the data
    disp = Tk()
    disp.wm_title('Displaying data Values')
    popJuvenilesTxt = Label (disp, text = popJ)
    popJuvenilesTxt.grid(row =1, column = 1)



def menu():  # creates the gui menu 

    menu = Tk()
    menu.wm_title("Greenfly model")

    genInp = Button(menu,text = "Set Generation Values")

    genVew = Button(menu,text = 'Dysplay Generation Values')

    modelCal = Button(menu,text = 'Run model')

    exportData = Button(menu,text = 'Export Data')

    genTxt = Label(menu, text='Input the Generation values')
    genvTxt = Label (menu, text = 'View the current generation values')
    modelTxt = Label (menu, text = 'Run the model')
    exportTxt = Label (menu, text = 'Export data')

    genInp.grid(row=1, column=1)
    genVew.grid(row=2, column=1)
    modelCal.grid(row=3, column=1)
    exportData.grid(row=4 , column=1)
    genTxt.grid(row=1, column = 2)
    genvTxt.grid(row=2, column =2)
    modelTxt.grid(row=3, column =2)
    exportTxt.grid(row=4, column = 2)
    genInp.configure(command = genInput)
    genVew.configure(command = genView)

menu()

The 'Submit' and the genView section keep returning 0 even though .get() is used. If StringVar is used it returns a blank space. The run model and export data functions are not yet implemented.


回答1:


the issue is that you are creating multiple Tk instances, for child windows you should be using Toplevel instead, so this works:

import sys
import tkinter
from tkinter import *
import time

global v


global popJ
popJ = 0

def genInput(): #Allows the user to input the data

    gen = Toplevel()
    gen.wm_title("Data Input")
    v = IntVar()
    ent1 = Entry(gen, textvariable = v).pack()
    ent1Txt = Label(gen, text = 'Input Juvenile Populations')

    ent1Txt.pack()


    v2 = StringVar()
    ent2 = Entry(gen, textvariable = v2)
    ent2Txt = Label(gen, text = 'Input Adult Populations')
    ent2.pack()
    ent2Txt.pack()

    v3 = StringVar()
    ent3 = Entry(gen, textvariable = v3)
    ent3Txt = Label(gen, text = 'Input Senile Populations')
    ent3.pack()
    ent3Txt.pack()

    v4 = StringVar()
    ent4 = Entry(gen, textvariable = v4)
    ent4Txt = Label(gen, text = 'Input Survival rates for Juveniles')
    ent4.pack()
    ent4Txt.pack()

    v5 = StringVar()
    ent5 = Entry(gen, textvariable = v5)
    ent5Txt = Label(gen, text = 'Input Survival rates for Adults')
    ent5.pack()
    ent5Txt.pack()

    v6 = StringVar()
    ent6 = Entry(gen, textvariable = v6)
    ent6Txt = Label(gen, text = 'Input Survival rates for Seniles')
    ent6.pack()
    ent6Txt.pack()

    v7 = StringVar()
    ent7 = Entry(gen, textvariable = v7)
    ent7Txt = Label(gen, text = 'Input the birth rate')
    ent7.pack()
    ent7Txt.pack()

    v8 = StringVar()
    ent8 = Entry(gen, textvariable = v8)
    ent8Txt = Label(gen, text = 'Number of Generations')
    ent8.pack()
    ent8Txt.pack()

    def quit1():   # Need to be here or it breaks the program
        gen.destroy()            
        return
    def submit():
        popJ = v.get()
        popJtxt = Label(gen, text= popJ).pack() # as stated in comments, this line will return none to popJtxt, so it pointless to assign it
        return

    submit1= Button(gen, text="Submit")
    submit1.pack()
    submit1.configure(command = submit)
    return1 = Button(gen, text = 'Return to Menu')
    return1.pack(pady=30)
    return1.configure(command = quit1)    
    return

def genView(): # should display the data
    disp = Toplevel()
    disp.wm_title('Displaying data Values')
    popJuvenilesTxt = Label (disp, text = popJ)
    popJuvenilesTxt.grid(row =1, column = 1)



def menu():  # creates the gui menu 

    menu = Tk()
    menu.wm_title("Greenfly model")

    genInp = Button(menu,text = "Set Generation Values")

    genVew = Button(menu,text = 'Dysplay Generation Values')

    modelCal = Button(menu,text = 'Run model')

    exportData = Button(menu,text = 'Export Data')

    genTxt = Label(menu, text='Input the Generation values')
    genvTxt = Label (menu, text = 'View the current generation values')
    modelTxt = Label (menu, text = 'Run the model')
    exportTxt = Label (menu, text = 'Export data')

    genInp.grid(row=1, column=1)
    genVew.grid(row=2, column=1)
    modelCal.grid(row=3, column=1)
    exportData.grid(row=4 , column=1)
    genTxt.grid(row=1, column = 2)
    genvTxt.grid(row=2, column =2)
    modelTxt.grid(row=3, column =2)
    exportTxt.grid(row=4, column = 2)
    genInp.configure(command = genInput)
    genVew.configure(command = genView)

menu()

to explain why this happens, you need to understand that all tk variables are created with an associated Tk instance (usually the first instance) so binding a variable belonging to one tk instance to a display created in another will never update the variable, creating a Toplevel instead of Tk associates it with the first Tk instance




回答2:


You shouldn't create more than one root / master window using Tk(). Change the Tk() calls in genInput() and genView() to Toplevel().

Also menu() should have a menu.mainloop() at the end of the function.

As furas mentions in the comments, the .pack() and .grid() methods return None, not the widget, so it's pointless storing the result of calling those methods.

A few other observations...

You import time but you don't appear to be using it. If you intend to use time.sleep() somewhere, please don't: it will not co-operate properly with Tkinter's event loop; there are other ways to do delays, using methods supplied by Tkinter.

You have import tkinter and also from tkinter import *. The import tkinter lets you refer to Tkinter entities by doing eg tkinter.Entry, but you're not using that syntax anywhere in your code. from tkinter import * lets you do Entry but the downside is that your script's namespace gets clobbered by all of the names that Tkinter defines. A better compromise is to use import tkinter as tk and then you can do tk.Entry, so you avoid the namespace pollution with only a tiny bit more typing.

Your code would be neater if you put it into a class. And that way you wouldn't need to use global. However, I should note that you aren't actually using global correctly in your code. You don't use it to "declare" a variable in the global scope, instead it should go inside a function (or method) definition to indicate that the function is modifying a name in the global scope.


Here's a "condensed" version of your program that sets and gets the popJ value correctly. This code was tested on Python 2.6.6, to run it on Python 3 you'll need to change the import statement to from tkinter import *.

from Tkinter import *

popJ = 0

def genInput(): #Allows the user to input the data
    gen = Toplevel()
    gen.wm_title("Data Input")
    v = IntVar()
    v.set(popJ)
    ent1 = Entry(gen, textvariable = v)
    ent1.pack()
    Label(gen, text = 'Input Juvenile Populations').pack()

    def quit1():   # Need to be here or it breaks the program
        gen.destroy()

    def submit():
        global popJ
        popJ = v.get()
        Label(gen, text=popJ).pack()
        return

    submit1= Button(gen, text="Submit")
    submit1.pack()
    submit1.configure(command = submit)
    return1 = Button(gen, text = 'Return to Menu')
    return1.pack(pady=30)
    return1.configure(command = quit1)

def menu():  # creates the gui menu
    menu = Tk()
    menu.wm_title("Greenfly model")
    genInp = Button(menu,text = "Set Generation Values")
    genInp.grid(row=1, column=1)
    genInp.configure(command = genInput)
    menu.mainloop()

menu()



回答3:


You have to use global popJ in submit.

Now you create local variable popJ in submit


EDIT: maybe global is not preferred method but it works in your example

import sys
import tkinter
from tkinter import*
import time

global v


global popJ
popJ = 0

def genInput(): #Allows the user to input the data

    gen = Toplevel()
    gen.wm_title("Data Input")
    v = IntVar()
    ent1 = Entry(gen, textvariable = v).pack()
    ent1Txt = Label(gen, text = 'Input Juvenile Populations')

    ent1Txt.pack()


    v2 = StringVar()
    ent2 = Entry(gen, textvariable = v2)
    ent2Txt = Label(gen, text = 'Input Adult Populations')
    ent2.pack()
    ent2Txt.pack()

    v3 = StringVar()
    ent3 = Entry(gen, textvariable = v3)
    ent3Txt = Label(gen, text = 'Input Senile Populations')
    ent3.pack()
    ent3Txt.pack()

    v4 = StringVar()
    ent4 = Entry(gen, textvariable = v4)
    ent4Txt = Label(gen, text = 'Input Survival rates for Juveniles')
    ent4.pack()
    ent4Txt.pack()

    v5 = StringVar()
    ent5 = Entry(gen, textvariable = v5)
    ent5Txt = Label(gen, text = 'Input Survival rates for Adults')
    ent5.pack()
    ent5Txt.pack()

    v6 = StringVar()
    ent6 = Entry(gen, textvariable = v6)
    ent6Txt = Label(gen, text = 'Input Survival rates for Seniles')
    ent6.pack()
    ent6Txt.pack()

    v7 = StringVar()
    ent7 = Entry(gen, textvariable = v7)
    ent7Txt = Label(gen, text = 'Input the birth rate')
    ent7.pack()
    ent7Txt.pack()

    v8 = StringVar()
    ent8 = Entry(gen, textvariable = v8)
    ent8Txt = Label(gen, text = 'Number of Generations')
    ent8.pack()
    ent8Txt.pack()

    def quit1():   # Need to be here or it breaks the program
        gen.destroy()            
        return
    def submit():
        global popJ

        popJ = v.get()
        popJtxt = Label(gen, text= v.get()).pack()
        return



    submit1= Button(gen, text="Submit")
    submit1.pack()
    submit1.configure(command = submit)
    return1 = Button(gen, text = 'Return to Menu')
    return1.pack(pady=30)
    return1.configure(command = quit1)    
    return

def genView(): # should display the data
    disp = Toplevel()
    disp.wm_title('Displaying data Values')
    popJuvenilesTxt = Label (disp, text = popJ)
    popJuvenilesTxt.grid(row =1, column = 1)



def menu():  # creates the gui menu 

    menu = Tk()
    menu.wm_title("Greenfly model")

    genInp = Button(menu,text = "Set Generation Values")

    genVew = Button(menu,text = 'Dysplay Generation Values')

    modelCal = Button(menu,text = 'Run model')

    exportData = Button(menu,text = 'Export Data')

    genTxt = Label(menu, text='Input the Generation values')
    genvTxt = Label (menu, text = 'View the current generation values')
    modelTxt = Label (menu, text = 'Run the model')
    exportTxt = Label (menu, text = 'Export data')

    genInp.grid(row=1, column=1)
    genVew.grid(row=2, column=1)
    modelCal.grid(row=3, column=1)
    exportData.grid(row=4 , column=1)
    genTxt.grid(row=1, column = 2)
    genvTxt.grid(row=2, column =2)
    modelTxt.grid(row=3, column =2)
    exportTxt.grid(row=4, column = 2)
    genInp.configure(command = genInput)
    genVew.configure(command = genView)
    menu.mainloop()

menu()

of course you need menu.mainloop() and Toplevel in place of Tk too.



来源:https://stackoverflow.com/questions/35010905/intvar-returning-only-0-even-with-get-function

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