2
\$\begingroup\$

I just finished my first GUI app, a Password Generator that can take any characters you want(I've added some default characters to make your life easier), and a password length up to 999, and some small features like copy to clipboard and clear button...

I used PyQt5 to build my GUI and some helpful modules like pyperclip, webbrowser...

This is what the app looks like on Windows:

enter image description here

I used Pyinstaller to convert .py to .exe download the Password Generator.exe here

Here's the source code:

#!/usr/bin/env python3.5.2


from PyQt5.QtWidgets import*
from PyQt5.QtCore import*
from PyQt5.QtGui import*
import random
import pyperclip
import webbrowser
import sys


class Password_Generator(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        layout = QGridLayout()

        self.menuBar = QMenuBar()
        self.default_characters = QPushButton()
        self.characters = QLineEdit()
        self.passwordlength = QLineEdit()
        self.pl_option = QComboBox()
        self.progress = QProgressBar()
        self.generate = QPushButton("Generate Password")
        self.result = QLineEdit()
        self.clipboard = QPushButton("Copy to clipboard")
        self.clear = QPushButton("Clear")

        self.fileMenu = QMenu("File", self)
        self.clearAction = self.fileMenu.addAction("Clear")
        self.exitAction = self.fileMenu.addAction("Exit")
        self.menuBar.addMenu(self.fileMenu)
        self.helpMenu = QMenu("Help", self)
        self.source_code = self.helpMenu.addAction("Source Code")
        self.information = self.helpMenu.addAction("About Me")
        self.menuBar.addMenu(self.helpMenu)
        self.characters.setPlaceholderText("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890$@^`,|%;.~()/\{}:?[]=-+_#!")
        self.characters.setFixedWidth(524)
        self.passwordlength.setPlaceholderText("password length")
        self.passwordlength.setFixedWidth(85)
        self.passwordlength.setAlignment(Qt.AlignHCenter)
        self.passwordlength.setValidator(QIntValidator(0, 999))
        self.passwordlength.setMaxLength(3)
        self.pl_option.setFixedWidth(58)
        self.pl_option.addItems(["Default", "8", "16", "32", "64", "128"])
        self.progress.setValue(0)
        self.progress.setAlignment(Qt.AlignHCenter)
        self.generate.setFixedWidth(125)
        self.default_characters.setFixedWidth(24)
        self.default_characters.setIcon(QIcon(r'C:\Users\SalahGfx\Desktop\Password Generator Files\file-default-icon-62367.png'))
        self.result.setReadOnly(True)
        self.result.setFixedWidth(425)

        layout.addWidget(self.default_characters, 0, 0)
        layout.addWidget(self.characters, 0, 1, 1, 2)
        layout.addWidget(self.passwordlength, 0, 3)
        layout.addWidget(self.pl_option, 0, 4)
        layout.addWidget(self.generate, 1, 0, 1, 2)
        layout.addWidget(self.result, 1, 2)
        layout.addWidget(self.progress, 1, 3, 1, 2)
        layout.addWidget(self.clipboard, 3, 0, 1, 3)
        layout.addWidget(self.clear, 3, 3, 1, 2)

        layout.setMenuBar(self.menuBar)
        self.setLayout(layout)
        self.setFocus()
        self.setWindowTitle("Password Generator")

        self.generate.clicked.connect(self.generated)
        self.clipboard.clicked.connect(self.clipboard_copy)
        self.clear.clicked.connect(self.cleared)
        self.default_characters.clicked.connect(self.default)
        self.pl_option.currentIndexChanged.connect(self.numbers)
        self.clearAction.triggered.connect(self.cleared)
        self.exitAction.triggered.connect(self.exit)
        self.source_code.triggered.connect(self.get_source_code)
        self.information.triggered.connect(self.info_window)

        self.new_window = Info_Window()
        self.new_window.setWindowIcon(QIcon(r'C:\Users\SalahGfx\Desktop\Password Generator Files\Lock_closed_key_2-512.png'))
        self.new_window.setWindowTitle("About Me")


    def get_source_code(self):
        webbrowser.open(r"C:\Users\SalahGfx\Desktop\Password Generator Files\Source Code.txt")

    def info_window(self):
        self.new_window.setWindowFlags(Qt.WindowCloseButtonHint)
        self.new_window.show()
        self.new_window.setFixedSize(665, 350)


    def exit(self):
        sys.exit(app.exec_())


    def numbers(self):
        if self.pl_option.currentText() == 'Default':
            self.passwordlength.setText(None)
        else:
            self.passwordlength.setText(self.pl_option.currentText())


    def default(self):
        characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890$@^`,|%;.~()/\{}:?[]=-+_#!"
        self.characters.setText(characters)


    def generated(self):
        try:
            characters = self.characters.text()
            password_length = int(self.passwordlength.text())
        except Exception:
            return

        self.password = ""
        for i in range(password_length):
            try:
                characters_index = random.randrange(len(characters))
            except Exception:
                return
            self.password = self.password + characters[characters_index]
            self.progress.setValue(100)
        self.result.setText(self.password)


    def clipboard_copy(self):
        if len(self.result.text()) > 0:
            pyperclip.copy(self.result.text())
            QMessageBox.information(self, "Information", "Password has been copied to clipboard!")
        else:
            return


    def cleared(self):
        self.characters.setText("")
        self.passwordlength.setText("")
        self.progress.setValue(0)
        self.result.setText("")
        self.passwordlength.setText(None)
        self.pl_option.setCurrentIndex(0)


class Info_Window(QDialog):
    def __init__(self):
        QDialog.__init__(self)

        info_layout = QGridLayout()

        self.info = QLabel("Password Generator\n"
                           "Version 1.0\n"
                           "Contact Riverbank at info@riverbankcomputing.com\n"
                           "Copyright © free 2016 Riverbank Computing Limited under GNU General Public License version 3\n"
                           "Contact Me at iteleport2015@gmail.com\n"
                           "Copyright © free 2017 Salah Gfx Open Source Project\n")
        self.about_me = QLabel("My name is Salah, I'm a college student, I study computer science and mathematics, I'm also a graphic designer\n"
                               "and python programmer, I'm a self taught, I have 3 years of experience in 3D design and 1 year in coding, I wish\n"
                               " to make 3D games in the future, combining those knowledges I believe I can make it, this app is my first GUI app,\n"
                               " I used to run all my codes and scripts in the console but now it feels different how you can share your work with\n"
                               " normal people, it is just amazing and helpful, have a nice day and I wish for you a successful life.")
        self.Font = QFont()
        self.Font.setBold(True)
        self.about_me.setFont(self.Font)
        self.Hline = QFrame()
        self.Hline.setFrameShape(self.Hline.HLine)
        self.Hline.setFrameShadow(self.Hline.Sunken)
        self.Vline = QFrame()
        self.Vline.setFrameShape(self.Vline.VLine)
        self.Vline.setFrameShadow(self.Vline.Sunken)
        self.image_label = QLabel()
        pixmap = QPixmap(r"C:\Users\SalahGfx\Desktop\Password Generator Files\SLH-GFX2.png")
        self.image_label.setPixmap(pixmap)

        info_layout.addWidget(self.info, 0, 2)
        info_layout.addWidget(self.Vline, 0, 1)
        info_layout.addWidget(self.image_label, 0, 0)
        info_layout.addWidget(self.Hline, 1, 0, 1, 3)
        info_layout.addWidget(self.about_me, 2, 0, 1, 3)

        self.setLayout(info_layout)




app = QApplication(sys.argv)
window = Password_Generator()
window.setFixedSize(732, 120)
window.setWindowIcon(QIcon(r'C:\Users\SalahGfx\Desktop\Password Generator Files\Lock_closed_key_2-512.png'))
window.show()
sys.exit(app.exec_())

The files needed here

\$\endgroup\$
3
\$\begingroup\$

You shouldn't use paths C:\Users\SalahGfx\Desktop\Password Generator Files\ - other user can put program in different folder and it will not work (even on other Windows).

You should use sys.argv[0] to get correct folder on any computer.
And then you can use os.path.join(folder, "some_file.png") to create path to images.


#!/usr/bin/env python3 should be enought - you don't have to set 3.5.2 - and it will work even if someone has 3.4 or 3.6 but don't have 3.5.2.


You don't need

else:
    return

Code will work without it


except Exception:
    return

It is not good practice to skip exception.
It could print message in console (using print())
so you could run it in terminal and see more information about problem.


Method exit() should rathern has name run() because app.exec_() starts Qt framework - it runs its engine (its mainloop/event-loop).

Besides, you have this method but you don't use it - you run sys.exit(app.exec_()) - but you could run window.exit()


You could read PEP8 - https://www.python.org/dev/peps/pep-0008/

It suggests to use UpperCase names for classes - without underscore
ie. PasswordGenerator, InfoWindow.

Even Qt doesn't use underscore in class names.

\$\endgroup\$
  • \$\begingroup\$ I will put your advice under care, thank you so much for your time \$\endgroup\$ – Salah Eddine May 16 '17 at 9:31
  • \$\begingroup\$ A further suggestion -- use print to log the type of error that happened, then insert a bare 'raise' statement (which preserves the stack trace/traceback). This will help you debug. Read more on exceptions: stackoverflow.com/questions/2052390/… \$\endgroup\$ – anonnoir May 16 '17 at 18:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.