Search code examples
pythonpyqt5appendpasswordsqlabel

PyQt5: Append multiple strings to a single QLabel


I've been working on this project for a while now, and everything is working as should be except the final piece.

Here is my code. The app takes a "number of passwords" input and a "length of passwords" input. When you click the "generate passwords" button it generates random passwords that should be appended to my app (self.textBox). However, instead of appending all the generated passwords, it only appends the last password that was generated in the loop.

Question: If I input 10 or 20 as my desired number of passwords, how can I get it to append them all in my app?

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QVBoxLayout, QPushButton, QLabel
import random


class App(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('Password Generator')
        self.setGeometry(100,100, 400, 400)
        self.intro = QLabel("Welcome to PyPass Gen 2.0")
        self.dialog1 = QInputDialog()
        self.dialog1.setOption(QInputDialog.NoButtons)
        self.dialog1.setLabelText('Number of passwords: ')
        self.dialog2 = QInputDialog()
        self.dialog2.setOption(QInputDialog.NoButtons)
        self.dialog2.setLabelText('Length of passwords: ')
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.intro, alignment=Qt.AlignCenter)
        self.layout.addWidget(self.dialog1)
        self.layout.addWidget(self.dialog2)
        self.textBox = QLabel()
        self.layout.addWidget(self.textBox, alignment=Qt.AlignCenter)
        self.button1 = QPushButton("Generate Passwords")
        self.button1.clicked.connect(self.execute)
        self.layout.addWidget(self.button1)

        self.setLayout(self.layout)
        self.show()

    def execute(self):
        char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()-_,./?'
        number_v = int(self.dialog1.textValue())
        length_v = int(self.dialog2.textValue())
        for password in range(number_v):
            self.passwords = ''
            for chars in range(length_v):
                self.passwords += random.choice(char)

                self.textBox.setText(self.passwords)

            print(self.passwords)
            # self.passwords.append(self.textBox)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

Solution

  • You should dynamically generate and delete textBoxes.

    I wrote below code exmaple.

    I added "self.textBoxes" for QLabel() containig list.

    Everytime you click the "Generate Passwords" buttons, all QLabels are deleted by "self.clearTextBoxes" function.

    All generated passwords are coverted into textBox(QLabel), and added to "self.layout2" (for textBox display).

    import sys
    from PyQt5.QtCore import Qt
    from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QVBoxLayout, QPushButton, QLabel
    import random
    
    
    class App(QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle('Password Generator')
            self.setGeometry(100,100, 400, 400)
            self.intro = QLabel("Welcome to PyPass Gen 2.0")
            self.dialog1 = QInputDialog()
            self.dialog1.setOption(QInputDialog.NoButtons)
            self.dialog1.setLabelText('Number of passwords: ')
            self.dialog2 = QInputDialog()
            self.dialog2.setOption(QInputDialog.NoButtons)
            self.dialog2.setLabelText('Length of passwords: ')
            self.layout = QVBoxLayout()
            self.layout.addWidget(self.intro, alignment=Qt.AlignCenter)
            self.layout.addWidget(self.dialog1)
            self.layout.addWidget(self.dialog2)
            self.layout2 = QVBoxLayout()
            self.layout.addLayout(self.layout2)
            self.textBoxes = []
            self.button1 = QPushButton("Generate Passwords")
            self.button1.clicked.connect(self.execute)
            self.layout.addWidget(self.button1)
    
            self.setLayout(self.layout)
            self.show()
    
        def execute(self):
            char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()-_,./?'
            number_v = int(self.dialog1.textValue())
            length_v = int(self.dialog2.textValue())
            self.clearTextBoxes()
            for password in range(number_v):
                self.passwords = ''
                for chars in range(length_v):
                    self.passwords += random.choice(char)
                    textBox = QLabel(self.passwords)
                print(self.passwords)
                self.textBoxes.append(textBox)
                self.layout2.addWidget(textBox)
                # self.passwords.append(self.textBox)
    
        def clearTextBoxes(self):
            for textBox in self.textBoxes:
                textBox.setParent(None)
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = App()
        sys.exit(app.exec_())