2

Two separate issues have come up with my code

First, I can't get the fourth row of my grid to appear, although the fifth appears to be displaying just fine.

Secondly, my passVal function keeps giving me the error:

passVal() takes 1 positional argument but 2 were given

I've tried rearranging things and converting it to a string and nothing seems to work.

I figure there's a chance it's one thing causing the same issue since they're both centered around the same button but I'm not sure.

import tkinter

class AccountCreation:
    def __init__(self):
        self.main = tkinter.Tk()
        self.main.title("Account Creation")

        self.topleftLabel = tkinter.Label(text="      ")
        self.topleftLabel.grid(row=1,column=1)
        self.botrightLabel = tkinter.Label(text="      ")
        self.botrightLabel.grid(row=5,column=5)

        self.promptLabel = tkinter.Label(text="Create a password with at least nine (9)\n characters that contains at least one digit, \n one uppercase, and one lowercase letter.\n\n")
        self.promptLabel.grid(row=2,column=2,columnspan=2)

        self.passLabel = tkinter.Label(text="Password:")
        self.passLabel.grid(row=3,column=2)
        self.passEntry = tkinter.Entry(width = 18, justify='right')
        self.passEntry.grid(row=3,column=3)

        self.enterButton = tkinter.Button(text="Enter", \
                                      command=self.passVal(self.passEntry.get()))
        self.enterButton.grid(row=4,column=2)
        self.cancelButton = tkinter.Button(text="Cancel", \
                                      command=self.cancel)
        self.cancelButton.grid(row=4,column=3)

        tkinter.mainloop()

def passVal(pw):
    if len(pw) < 9:
       print ("no")

def cancel(self):
    self.main.destroy()

my_gui = AccountCreation()
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79
Amanda
  • 43
  • 4
  • BTW you don't need to use labels for spacing. You can use padding for that. – Mike - SMT Oct 03 '17 at 14:36
  • @BryanOakley, I don't think this question is a duplicate of the post you referenced. This questions problem was more related to the missing `self` argument in the `passVal` method. Yes there was also the matter of the command execution on init but that was not the main question/problem. – Mike - SMT Oct 03 '17 at 15:08
  • @Mike-SMT: fair enough. – Bryan Oakley Oct 03 '17 at 15:24

1 Answers1

2

Aside from the indention issues you are having, all methods in a class you need to pass self as the first argument unless you are using special tags that can make it a stand alone function.

Change:

def passVal(pw):

To:

def passVal(self, pw):

You will also need to change the command on you Enter button to use lambda in order to prevent python from calling the passVal method on start up.

Change:

command=self.passVal(self.passEntry.get())

To:

command=lambda: self.passVal(self.passEntry.get())

You don't really need to use a lambda here or even pass the argument of self.passEntry.get(). You can get the value of the entry field in the passVal() method by use self.passEntry.get() instead of pw.

If you change this:

command=lambda: self.passVal(self.passEntry.get())

To this:

command=self.passVal

And this:

def passVal(self, pw):
    if len(pw) < 9:
        print ("no")

To this:

def passVal(self):
    if len(self.passEntry.get()) < 9:
        print ("no")

You program will work fine and you can avoid using a lambda in your command.

Note: You do not need to use labels as spacers. You can simple use padx and pady in your grid placement.

Take a look at the below code:

import tkinter

class AccountCreation:
    def __init__(self):
        self.main = tkinter.Tk()
        self.main.title("Account Creation")

        self.promptLabel = tkinter.Label(text="Create a password with at least nine (9)\n characters that contains at least one digit, \n one uppercase, and one lowercase letter.\n\n")
        self.promptLabel.grid(row=2,column=2,columnspan=2,pady=(10,10))

        self.passLabel = tkinter.Label(text="Password:")
        self.passLabel.grid(row=3,column=2)
        self.passEntry = tkinter.Entry(width = 18, justify='right')
        self.passEntry.grid(row=3,column=3)

        self.enterButton = tkinter.Button(text="Enter", \
                                          command=self.passVal(self.passEntry.get()))
        self.enterButton.grid(row=4,column=2)
        self.cancelButton = tkinter.Button(text="Cancel", \
                                          command=self.cancel)
        self.cancelButton.grid(row=4,column=3,pady=(10,10))

        tkinter.mainloop()

    def passVal(self, pw):
        if len(pw) < 9:
            print ("no")

    def cancel(self):
        self.main.destroy()

my_gui = AccountCreation()

Notice that simple using pady=(10,10) we have put space at the top and bottom of the widget.

Mike - SMT
  • 14,784
  • 4
  • 35
  • 79