# Password Generator using Python and Tkinter (Part-I)

## Introduction

This is the first blog of the Password Manager using Tkinter series where we are going to create a Password Generator application that will be able to generate strong passwords for us. Since this will be a *Graphical User Interface(GUI)* application, it doesn't rely on any kind of web connection. This will be a very short blog since the application we are building is quite small. So, let's see what libraries and concepts we are going to use in this application:

*   [tkinter module](https://docs.python.org/3/library/tkinter.html)
*   [secrets module](https://docs.python.org/3/library/secrets.html)
*   [Python Classes](https://docs.python.org/3/tutorial/classes.html)

So, without further ado, let's get started.

![](https://res.cloudinary.com/dlomjljb6/image/upload/v1/media/blog/uploads/2021/10/29/tenor%5Fxcm6ox)

## Password Generator Class

Let's start by creating a `PasswordGenerator` class and define the constructor for it as:

```py
from tkinter import Button, Entry, Frame, Label, LabelFrame, Tk

class PasswordGenerator:

    def __init__ (self):
        self.window = Tk()
        self.window.title("Password Generator")
        self.window.geometry("450x300")

        # Label Frame
        self.label_frame = LabelFrame(
            self.window, text="Enter the number of characters")
        self.label_frame.pack(pady=20)

        # Entry box for number of characters
        self.length_entry_box = Entry(self.label_frame, width=20)
        self.length_entry_box.pack(padx=20, pady=20)

        # Declaring feedback if no length is found
        self.feedback = Label(self.window)

        # Entry box for password
        self.password_entry_box = Entry(
            self.window, text="", width=50)
        self.password_entry_box.pack(pady=20)

        # Frame for buttons
        self.button_frame = Frame(self.window)
        self.button_frame.pack(pady=20)

        # Generate Password Button
        generate_btn = Button(
            self.button_frame, text="Generate Password", command=self.generate_random_password)
        generate_btn.grid(row=0, column=0, padx=10)

        # Copy Password Button
        copy_btn = Button(self.button_frame,
                          text="Copy Password", command=self.copy_password)
        copy_btn.grid(row=0, column=1, padx=10)

```

In the above script, first of all, we created a window of *width 450* and *height 300* with the *title Password Generator*.

![](https://res.cloudinary.com/dlomjljb6/image/upload/v1635523922/media/blog/uploads/2021/10/29/test1%5Fojt0x2.png)

Next, if you see in the above output, we have a frame where we have placed an input field so that users can enter the number of characters their password should have. So for that, we have created a *LabelFrame* called `label_frame` and packed it with a padding of 20 on the y-axis. Inside the `label_frame`, we have placed an *Entry* for password length input called `length_entry_box` with a width of 20 and padding of 20 on both x-axis and y-axis.

![](https://res.cloudinary.com/dlomjljb6/image/upload/v1/media/blog/uploads/2021/10/29/test2%5Fhpr5dd)

Next, we have an input field where the generated password will appear. For creating the password entry box called `password_entry_box`, we are again using the *Entry* class and gave it a width of 50 (since the password can be lengthy too) and a padding of 20 on the y-axis. Above that, we have created a label called `feedback` using the *Label* class to show an error message if a user doesn't enter any length and presses Generate Password button.

Below that we'll have a frame called `button_frame` where our Generate Password and Copy Password buttons will be placed. So to create these buttons, we have used the *Button* class. The thing to be noticed is we have used two commands - `generate_random_password` and `copy_password` for the Generate Password button and Copy Password button respectively. We'll be creating these two methods very soon. We are using grid to place these two buttons in a row.

## Generate Password

In the previous section, we saw that we had a `generate_random_password` method being called when the Generate Password button was clicked. So, let's create that in the *PasswordGenerator* class itself:

```py
import string
from secrets import choice

UPPERCASE = list(string.ascii_uppercase)
LOWERCASE = list(string.ascii_lowercase)
NUMBER = list(string.digits)
SYMBOLS = ['@', '#', '$', '%', '&', '_']

def generate_random_password(self):
    self.password_entry_box.delete(0, END)
    try:
        password_length = int(self.length_entry_box.get())
        self.feedback.destroy() # Destroy feedback if length is there
        data = UPPERCASE+LOWERCASE+NUMBER + SYMBOLS
        password = ''.join(choice(data) for _ in range(password_length))
        self.password_entry_box.insert(0, password)
    except ValueError:
        self.feedback = Label(self.window, fg="red", text="Please enter number of characters")
        self.feedback.place(x=130, y=100)

```

First of all, we have imported `string` and `choice`(from secrets module). We have then created a few constants such as **UPPERCASE** , **LOWERCASE** , **NUMBER** and **SYMBOLS**. These constants are Python lists and will be useful when we'll be generating random passwords.

Next, inside the `generate_random_password()` method, we have first deleted whatever is already present in the password entry box. This is important because we can click on the Generate Password button as many times we want, hence the previous value should be erased before placing the new value. We're then using try-catch block. Inside the try block, we are fetching the value of password length using the `get()` method provided by the *Entry* class. We are then converting it into int value. This is where an error can occur when the user doesn't enter any value and clicks on Generate Password button. We are then destroying the feedback message(if any). We are then generating a random password of the desired length using the constants declared above and the `choice`method. Once a new password is generated, it is placed in the `password_entry_box`.

If the error occurs, we are catching it in the except block and replace the `feedback` with the error message.

## Copy Password

This method will be pretty simple and we'll be using two pre-defined methods given by our Tkinter window.

```py
def copy_password(self):
    self.window.clipboard_clear()
    self.window.clipboard_append(self.password_entry_box.get())

```

First, we are clearing our clipboard so that if anything is already copied, it is erased. Then we are appending the value which is placed in the `password_entry_box`.

## Run the Mainloop

To run the mainloop, we are using main method as:

```py
if __name__ == ' __main__':
    PasswordGenerator().window.mainloop()

```

## Final Code and Output

Now we are done with our coding part, and you can find the entire code below:

```py
from tkinter import Button, Entry, Frame, Label, LabelFrame, Tk
import string
from secrets import choice
from tkinter.constants import END

UPPERCASE = list(string.ascii_uppercase)
LOWERCASE = list(string.ascii_lowercase)
NUMBER = list(string.digits)
SYMBOLS = ['@', '#', '$', '%', '&', '_']

class PasswordGenerator:

    def __init__ (self):
        self.window = Tk()
        self.window.title("Password Generator")
        self.window.geometry("450x300")

        # Label Frame
        self.label_frame = LabelFrame(
            self.window, text="Enter the number of characters")
        self.label_frame.pack(pady=20)

        # Entry box for number of characters
        self.length_entry_box = Entry(self.label_frame, width=20)
        self.length_entry_box.pack(padx=20, pady=20)

        # Declaring feedback if no length is found
        self.feedback = Label(self.window)

        # Entry box for password
        self.password_entry_box = Entry(
            self.window, text="", width=50)
        self.password_entry_box.pack(pady=20)

        # Frame for buttons
        self.button_frame = Frame(self.window)
        self.button_frame.pack(pady=20)

        # Generate Password Button
        generate_btn = Button(
            self.button_frame, text="Generate Password", command=self.generate_random_password)
        generate_btn.grid(row=0, column=0, padx=10)

        # Copy Password Button
        copy_btn = Button(self.button_frame,
                          text="Copy Password", command=self.copy_password)
        copy_btn.grid(row=0, column=1, padx=10)

    def generate_random_password(self):
        self.password_entry_box.delete(0, END)
        try:
            password_length = int(self.length_entry_box.get())
            self.feedback.destroy() # Destroy feedback if length is there
            data = UPPERCASE+LOWERCASE+NUMBER + SYMBOLS
            password = ''.join(choice(data) for _ in range(password_length))
            self.password_entry_box.insert(0, password)
        except ValueError:
            self.feedback = Label(self.window, fg="red",
                                  text="Please enter number of characters")
            self.feedback.place(x=130, y=100)

    def copy_password(self):
        self.window.clipboard_clear()
        self.window.clipboard_append(self.password_entry_box.get())

if __name__ == ' __main__':
    PasswordGenerator().window.mainloop()

```

#### **Output Screenshots**

**![](https://res.cloudinary.com/dlomjljb6/image/upload/v1635523591/media/blog/uploads/2021/10/29/screenshot-2021-10-29-213552%5Fqagnor.png)**

**![](https://res.cloudinary.com/dlomjljb6/image/upload/v1/media/blog/uploads/2021/10/29/screenshot-2021-10-29-221807%5Fmvrq2x)**

**![](https://res.cloudinary.com/dlomjljb6/image/upload/v1/media/blog/uploads/2021/10/29/screenshot-2021-10-29-221855%5Fsplibf)**

## Conclusion

In this part, we've created a Password Generator. In the upcoming part, we'll be creating a Password Manager which will be able to store our password, that too with encryption, in a SQL database. We'll also integrate this Password Generator inside that application. So, stay tuned!
