简体   繁体   English

通过检查按钮小部件在Tkinter中分配全局变量

[英]assigning a global variable in Tkinter from a checkbutton widget

I've been working on a crude Tkinter population growth calculator type project, and it works fine with just the population consistently growing with no decay or lowered birth rate. 我一直在进行一个粗略的Tkinter人口增长计算器类型的项目,并且该项目在人口持续增长且没有衰退或出生率降低的情况下仍然可以正常工作。 I have been trying to get a variable to be considered global so it can be read in my function that calculates the population. 我一直在尝试将变量视为全局变量,以便可以在计算总体的函数中读取该变量。

However I can't seem to figure out how to assign a value to the variable when the checkbutton widget is checked or not. 但是,我似乎无法弄清楚在未选中checkbutton小部件时如何为变量赋值。 Here is the code for you guys to see: 这是供您查看的代码:

'''shows human population growth rate through a certain year.
   It also has an option to include a list of prepared disasters
   that can lower the population.'''

from math import *
from Tkinter import *
import random

class App(Tk):
    def __init__ (self):
        Tk.__init__(self)
        '''Creates the set up for the Tkinter widgets with text on the left side, and the entry values on the right'''
        self.title("Population Growth")

        self.LblOutput = Label (self, foreground = "blue", font = "arial", text = "Enter the year you wish to see the world's population: ")
        self.LblOutput.grid(row = 1, column = 0)

        self.TxtInput = Entry(self)
        self.TxtInput.grid(row = 1, column = 1)

        self.LblOutput2 = Label (self, foreground = "blue", font = "arial", text = "Enter the desired Starting population: ")
        self.LblOutput2.grid(row = 2, column = 0)

        self.TxtInput2 = Entry(self)
        self.TxtInput2.grid(row = 2, column = 1)

        Label(self, foreground = "blue", font = "arial", text = "Turn on Natural Disasters?").grid(row = 3, column = 0)
        self.checkVar = IntVar()
        self.chkCheck = Checkbutton(self, text = "Natural Disasters", variable = self.checkVar, onvalue = 1, offvalue = 0, command = self.mortality)
        self.chkCheck.grid(row = 3, column = 1)

        self.StrtBtn = Button(self, foreground = "black", font = "arial", text = "Begin!", command = self.population_growth)
        self.StrtBtn.grid (row = 6, column = 0)

        self.TxtOutput = Label(self, foreground = "red", font = "gothica" , text = "The Population Is:").grid(row = 7, column = 0)
        self.LblTotal = Label(self)
        self.LblTotal.grid(row = 7, column = 1)

        self.mainloop()

    def mortality(self):
    '''checks to see if the checkmark is checked, if so assigns a random number to deathrate from the range, otherwise deathrate is 0'''
        if self.checkVar.get() == 1:
            deathrate = random.uniform(0.001, 0.00009903)
        elif self.checkVar.get() == 0:
            deathrate = 0
        global deathrate

    def population_growth(self):
        #Using the following equation P=P(subscript = 0)e^rt
        #P(subscript = 0)=initial population, 0 = time; for simplicity = p
        #e = euler's number [approximation]
        #rate_of_growth = rate of growth (found by subtracting crude death rate from crude birth rate
        #time_desired = time (years) that the population is calculated for
        time_desired = int(self.TxtInput.get())
        population_beginning = int(self.TxtInput2.get())
        e_mans_number = 2.71828182845904523536028747135266249775724709369995
        rate_of_growth = 0.01113 - int(deathrate)
        P = population_beginning * ((e_mans_number)**((rate_of_growth)*(time_desired)))
        self.LblTotal["text"] = " %d  people" % P 

def main():
    a = App()

if __name__ == "__main__":
    main()

It seems to work fine if I check the box, but once unchecked the value does not change. 如果我选中此框,则似乎工作正常,但一旦取消选中,该值就不会更改。 If I start it with the value unchecked it will give me an error, but once I check it, no error. 如果我使用未选中的值启动它,则会给我一个错误,但是一旦我对其进行检查,就不会出错。 After checking it, and deselecting it, no error, any help??? 检查后,并取消选择它,没有错误,没有任何帮助???

Initialise deathrate before class with the imports deathrate前通过进口初始化deathrate

Whenever changing the value of deathrate do: 每当更改deathrate的值时, deathrate执行以下操作:

global deathrate

before changing the value. 更改值之前 Rest of your code is working fine 您的其余代码工作正常

Why make a global variable out of it? 为什么要使用全局变量? Global variables are a bad habit most of the time. 大多数时候,全局变量是一种坏习惯。

Try the following: 请尝试以下操作:

class App(Tk):

def __init__ (self):
    Tk.__init__(self)
    '''Creates the set up for the Tkinter widgets with text on the left side, and the          entry values on the right'''
    self.title("Population Growth")
    self.deathRate = random.uniform(0.001, 0.00009903)
    [...]

Now you can access the variable deathRate within your mortality and population growth function via: 现在,您可以通过以下方式访问死亡率和人口增长函数中的变量deathRate:

self.deathrate

For example: 例如:

    def mortality(self):
        if self.checkVar.get() == 1:
            self.deathrate = random.uniform(0.001, 0.00009903)
        elif self.checkVar.get() == 0:
            self.deathrate = 0

    def population_growth(self):
        time_desired = int(self.TxtInput.get())
        population_beginning = int(self.TxtInput2.get())
        e_mans_number = 2.71828182845904523536028747135266249775724709369995
        rate_of_growth = 0.01113 - int(self.deathrate)
        P = population_beginning * ((e_mans_number)**((rate_of_growth)*(time_desired)))
        self.LblTotal["text"] = " %d  people" % P 

This is called an instance variable. 这称为实例变量。 Please refer to http://www.python.org/doc/essays/ppt/acm-ws/sld051.htm or the python tutorial( http://docs.python.org/2/tutorial/classes.html ). 请参考http://www.python.org/doc/essays/ppt/acm-ws/sld051.htm或python教程( http://docs.python.org/2/tutorial/classes.html )。

Greetings 问候

You don't need to create a global variable, and you don't need to do anything when the checkbutton is checked. 您无需创建全局变量,并且在选中复选按钮时无需执行任何操作。 Just use the checkbutton variable at the time that you need it: 只需在需要时使用checkbutton变量:

def population_growth(self):
    ...
    deathrate = 0
    if self.checkVar.get() == 1:
        deathrate = random.uniform(0.001, 0.00009903)
    rate_of_growth = 0.01113 - deathrate

If you don't want to put that logic in the function, just declare another instance variable. 如果您不想将该逻辑放入函数中,只需声明另一个实例变量即可。 Instead of using a global, use self.deathrate: 代替使用全局,使用self.deathrate:

def mortality(self):
    if self.checkVar.get() == 1:
        self.deathrate = random.uniform(0.001, 0.00009903)
    else:
        self.deathrate = 0

def population_growth(self):
    ...
    rate_of_growth = 0.01113 - self.deathrate

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM