简体   繁体   中英

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_())

You can create a list for the passwords, and then use str.join to make a block of text to put in your label. You can also use random.choices to create each password more simply. But note that this will allow repeated characters . To avoid that, you could use random.sample instead:

def execute(self):
    chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()-_,./?'
    number_v = int(self.dialog1.textValue())
    length_v = int(self.dialog2.textValue())
    passwords = []
    for count in range(number_v):
        password = ''.join(random.choices(chars, k=length_v))
        # use this for no repeated characters
        # password = ''.join(random.sample(chars, k=length_v))
        passwords.append(password)
    self.textBox.setText('\n'.join(passwords))

NB : it is better to use the secrets module to generate passwords, as it will create much stronger passwords.

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_())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM