how to change value of label after button is click

2019-09-16 11:11发布

问题:

I am creating a simple bank account GUI , when i click the menu " interest" the variable changed from 1 to 2 , which should change the value of the current balance by 10 percent, however the value stays the same, give your insight.

from tkinter import *
from random import randint


class BankAccount(object):
    def __init__(self, initial_balance=0):
        self.balance = initial_balance
    def deposit(self, amount):
        self.balance += amount
    def withdraw(self, amount):
        self.balance -= amount       
    def get_balance(self, initial_balance, rate):
        return self.get_balance() * self._rate

class BankAccountWithInterest(BankAccount):
    def __init__(self, initial_balance=0, rate=0.1):
        BankAccount.__init__(self, initial_balance)
        self._rate = rate           
    def interest(self):
        return self.balance * self._rate

balance = (randint(100, 500))
my_account = BankAccount(balance)
my_interest = BankAccountWithInterest(balance)
interest = my_interest.balance + my_interest.interest()

typeOfAccount = "1"
class GUI:
    def __init__(self, master):
        frame = Frame(master)
        frame.pack()


        #Toolbar#

        toolbar = Frame(root)
        toolbar.pack(side=TOP, fill=X)

        #Button#

        button1 = Button(toolbar, text="Deposit", width = 13,    command=self.depositBalance)
        button2 = Button(toolbar, text="Withdraw",width = 13, command=self.depositWithdraw)
        button1.pack(side=LEFT)
        button2.pack(side=RIGHT)

        #Menu#

        subMenu = Menu(menu)
        menu.add_cascade(label="Type of Account", menu=subMenu)
        subMenu.add_command(label="Standard", command= self.standard)
        subMenu.add_command(label="Interest", command= self.interest)

        #Textbox#

        self.text = Entry(root)
        self.text.pack()

        #Labels#

        w = Label(root, text="Current Balance:")
        w.pack()
        w1 = tkinter.StringVar()
        if typeOfAccount == "1":
            w1 = Label(root, text=my_account.balance)
            w1.pack()
        elif typeOfAccount == "2":
            w1.set(text=interest)
            w1.pack()


    def depositBalance(self):
            a = int(self.text.get())
            my_account.balance = a + my_account.balance
            print(my_account.balance)

    def depositWithdraw(self):
            a = int(self.text.get())
            my_account.balance = my_account.balance - a
            print(my_account.balance)         

    def standard(self):
        typeOfAccount = "1"

    def interest(self):
        typeOfAccount = "2"


root = Tk()
menu = Menu(root)
root.config(menu=menu)
root.title("Bank Account")
root.minsize(width=250, height=100)
root.maxsize(width=300, height=150)
GUI(root)

root.mainloop()

回答1:

There are several problems with your code. The multiple class files do not appear to work as you think they should and some things are just wrong. I have reworked your program into what I think it is you are trying to do and I have moved everything into 1 big class as it made more sense in this situation. You were making things more complicated than it needed to be by creating variables outside of the classes and by making several classes. There is nothing really wrong with using several classes but the way you were going about it was making things way more difficult than it needed to be.

First thing I did was to create all the class variables/attributes that we are going to use.

To make things easier on us going forward I made every widget and variable a class attribute by placing self. as a prefix to all the variable/widget names. This will allow us to interact with and change each attribute in any of the class methods without an issue and if you add more options down the road the attributes will already be defined and ready to change.

Next I moved all your separate class methods into the main class to make things easier to work with.

I replaced your if/else statement on the account types into a methods. This will allow us to update label to show the balance or the interest any time the account type changes or an amount is added or removed from the balance.

I modified the depositBalance and depositWithdraw methodsto have a little error handling because your entry field is not restricted to only numbers and can cause errors if the user puts anything else in or leaves it blank.

I change the standard and interest methods to update the typeOfAccount attribute and to update the label by calling on the type_account method.

Last but not least some general clean up so the code did not have pointless spacing and to make sure we follow a DRY (don't repeat yourself) standard.

Below is the reworked code with all the changes I mentioned above. Let me know if this helps and if you are confused on anything.

from tkinter import *
from random import randint

class GUI:
    def __init__(self, master):

        self.master = master
        self.typeOfAccount = "1"
        self.balance = (randint(100, 500))
        self.rate = 0.1

        self.frame = Frame(master)
        self.frame.pack()

        self.toolbar = Frame(root)
        self.toolbar.pack(side=TOP, fill=X)

        self.button1 = Button(self.toolbar, text="Deposit", width = 13, command=self.depositBalance)
        self.button2 = Button(self.toolbar, text="Withdraw",width = 13, command=self.depositWithdraw)
        self.button1.pack(side=LEFT)
        self.button2.pack(side=RIGHT)

        self.menu = Menu(self.master)
        self.master.config(menu = self.menu)
        self.subMenu = Menu(self.menu)
        self.menu.add_cascade(label="Type of Account", menu=self.subMenu)
        self.subMenu.add_command(label="Standard", command=self.standard)
        self.subMenu.add_command(label="Interest", command=self.interest)

        self.text = Entry(self.master)
        self.text.pack()

        self.w = Label(root, text="Current Balance: {}".format(self.balance))
        self.w.pack()
        #removed "tkinter." not needed because of the type of import you used
        self.w1 = StringVar()

    def type_account(self):
        if self.typeOfAccount == "1":
            self.w.config(text="Current Balance: {}".format(self.balance))

        elif self.typeOfAccount == "2":
            interest = self.balance * self.rate
            self.w.config(text="Current Balance: {}".format(interest))

    def depositBalance(self):
        try:
            if int(self.text.get()) > 0:
                a = int(self.text.get())
                self.balance = a + self.balance
                self.type_account()
        except:
            print("Blank or non numbers in entry field")

    def depositWithdraw(self):
        try:
            if int(self.text.get()) > 0:
                a = int(self.text.get())
                self.balance = self.balance - a
                self.type_account()
        except:
            print("Blank or non numbers in entry field")

    def standard(self):
        self.typeOfAccount = "1"
        self.type_account()

    def interest(self):
        self.typeOfAccount = "2"
        self.type_account()

if __name__ == "__main__":

    root = Tk()
    root.title("Bank Account")
    root.minsize(width=250, height=100)
    root.maxsize(width=300, height=150)

    app = GUI(root)

    root.mainloop()


回答2:

You should set self.w1, (rather than just w1) for example, then you can update the text from any instance method in that class.