0

I am having trouble making a placeholder in this code, when I do it in a separate window following previous posts on SO it works fine, however when I try to adapt that code into my code it doesn't work. It just leaves a blank textbox with no placeholder. Give your insight please.

from tkinter import *
from random import randint
import time

class Account:
    def __init__(self, init_balance=0):
        self.balance = init_balance
    def deposit(self, amount):
        self.balance += amount
    def withdraw(self, amount):
        self.balance -= amount
    def get_balance(self):
        return self.balance

class InterestAccount(Account):
    def __init__(self, init_balance=0, rate=0.1):
        super().__init__(init_balance)
        self._rate = rate
    def interest(self):
        return self.balance * self._rate   
    def deposit(self, amount):
        interest += amount
    def withdraw(self, amount):
        interest -= amount


class GUI(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.title('Bank Account')


        #Menu#
        menu = Menu(self)
        acct_type_menu = Menu(menu)
        menu.add_cascade(label='Account Type', menu=acct_type_menu)
        acct_type_menu.add_command(label='Standard', command=self.set_type_standard)
        acct_type_menu.add_command(label='Interest', command=self.set_type_interest)
        self.config(menu=menu)

        #Account#
        start_balance = randint(100, 500)
        self.acct = Account(start_balance)
        self.my_interest = InterestAccount(start_balance)
        self.interest = self.my_interest.balance + self.my_interest.interest()

        #Labels#
        Label(self, text='Current Balance:').pack()
        self.balance_label = Label(self, text='Select account type')
        self.balance_label.pack()

        #Button#
        btns_frame = Frame(self)
        btns_frame.pack(side=TOP, fill=X)

        Button(btns_frame, text='Deposit', width=13, command=self.deposit).pack(side=LEFT)
        Button(btns_frame, text='Withdraw', width=13, command=self.withdraw).pack(side=RIGHT)
-----------------------------------------------> HIGHLIGHTED  
        #Textbox#

        vcmd = (self.register(self.onValidate), '%S')
        self.text = Entry(self, validate='key', vcmd=vcmd)
        self.text.pack()
        self.text.pack()
        placeholder_text = 'some text'
        self.text.insert(0, placehoder_text)
        self.text.bind("<Button-1>", lambda event: clear_entry(self))

    def clear_entry(self):
        self.text.delete(0, END)
        self.text.pack()

    def onValidate(self, S):
        if S in '0123456789.':
            return True
        return False
---------------------------------------------> HIGHLIGHTED 


    def set_type_standard(self):
        self.acct_type = 'standard'
        self.balance_label.config(text=round(self.acct.balance, 2))

    def set_type_interest(self):
        self.acct_type = 'interest'
        self.balance_label.config(text=round(self.interest, 2))

    def deposit(self): 
        if self.acct_type == 'interest':
            a = int(self.text.get())
            self.interest += a
            self.balance_label.config(text=round(self.interest, 2))
        elif self.acct_type == 'standard':
            a = int(self.text.get())
            self.acct.balance += a
            self.balance_label.config(text=round(self.acct.balance, 2))
        else:
            self.balance_label.config(text='Select account type')
            self.clear_entry()

    def withdraw(self):
        if self.acct_type == 'interest':
            a = int(self.text.get())
            self.interest -= a
            self.balance_label.config(text=round(self.interest, 2))
        elif self.acct_type == 'standard':
            a = int(self.text.get())
            self.acct.balance -= a
            self.balance_label.config(text=round(self.acct.balance, 2))
        else:
            self.balance_label.config(text='Select account type')
            self.clear_entry()


if __name__ == '__main__':
    GUI().mainloop()
CDspace
  • 2,639
  • 18
  • 30
  • 36
  • Hello again Mohamed. Please reduce your code to a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). There is no reason to display the full code for the issue you are having. That being said I can see a few things wrong with it already. your methods `deposit` and `withdraw` in the `InterestAccount` class do nothing. It is looking for a local variable interest that does not exist and it cannot += or -= a non existent variable. Also change the `clear_entry(self)` command in the self.text.bind to `self.clear_entry()` – Mike - SMT Jul 20 '17 at 15:56
  • Also you question does not have enough context for us to answer. What exactly are you expecting the place holder to do. Can you link the previous SO post where you say you get this placeholder from? – Mike - SMT Jul 20 '17 at 16:01
  • Thank you, sorry will do next time i post – Mohamed Ismail Jul 20 '17 at 16:01
  • https://stackoverflow.com/questions/45217057/how-to-add-a-placeholder-in-tkinter – Mohamed Ismail Jul 20 '17 at 16:09
  • Your placeholder text `'some_text'` does not consist of a single digit or decimal point, and therefore its insertion is being blocked by your validation function. Perhaps you could enable the validator only after clearing the placeholder text - I don't see any easy way to combine these two functionalities. – jasonharper Jul 20 '17 at 16:11
  • even after removing it from the textbox field, there is still no placeholder – Mohamed Ismail Jul 20 '17 at 16:13

1 Answers1

0

You do have a few other problems in your code as I mentioned in the comments of your question but this answer will focus on why your placeholder is not working.

The validation argument in your self.text entry widget is blocking anything but numbers from being placed. So this is why your placeholder_text is not working.

You can either change your place holder to have the value of 0 or "0". Or remove the validation = 'key' part.

BTW there is a spelling error in your placeholder text.

Change:

self.text.insert(0, placehoder_text)

to:

self.text.insert(0, placeholder_text)

UPDATE:

Per your request I have added some issues below I noticed in your code that need your attention.

In the class InterestAccount(Account):

    # Both the below methods don't do anything of use.
    # The variable (interest) is a local variable in this case and needs
    # to be assigned a value before you can add to or subtract from it.
    # In the Eclipse IDE at least the code wont even run
    # until these 2 methods have been fixed.
    def deposit(self, amount):
        interest += amount
    def withdraw(self, amount):
        interest -= amount

In the class GUI(Tk):

        # Here you are using the argument validate='key'.
        # This is not a big deal but will prevent the 
        # insert(0, placeholder_text) from working because
        # the value of placeholder_text is not a number.
        self.text = Entry(self, validate='key', vcmd=vcmd)

        # you have packed the self.text widget twice here.
        # just remove one of the packs as it is not needed.
        self.text.pack()
        self.text.pack()
        placeholder_text = 'some text'

        # There is a typo here for placehoder_text.
        # Change it to placeholder_text.
        self.text.insert(0, placehoder_text)

        # Because you are calling a method of a class the clear_entry(self)
        # needs to be changed to self.clear_entry() instead. 
        self.text.bind("<Button-1>", lambda event: clear_entry(self))

        # There is no reason to pack the text box here as it is already packed
        # just delete the self.text.pack() here.
    def clear_entry(self):
        self.text.delete(0, END)
        self.text.pack()
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79