Вывод текста из функции класса? — Tkinter

#python #tkinter

#python #tkinter

Вопрос:

Прошу прощения, если я не использую правильную терминологию, я новичок в Python и делал это неторопливо для удовольствия. Я пытаюсь разобраться во всем сам, посмотрев несколько руководств и прочитав онлайн. Проблема, с которой я столкнулся, заключается в том, что я хотел создать графический интерфейс для генератора паролей Python (очень простой первый проект.) Я создал то, что считал правильным форматом, но у меня возникла проблема с отображением функции в окне графического интерфейса, а не в терминале. Я думаю, что это когда я прихожу к self.output, где это все портит.

 class GenPass:
    def __init__(self, master):
        frame = Frame()
        frame.pack()

        self.printButton = Button(frame, text="Generate Password", padx=4, pady=4, command=self.generate)
        self.printButton.pack(side=LEFT)

        self.quitButton = Button(frame, text="Copy to Clipboard", padx=4, pady=4, command=master.destroy)
        self.quitButton.pack(side=LEFT)

        self.output = Label(frame, fg="Green")
        self.output.place(x=240, y=85)
        self.output.config(text=self.generate)

    def generate(self):
        for i in range(3):
            print(random.choice(Words).capitalize(), end='')
        for i in range(2):
            print(random.choice(Numbers), end='')
        for i in range(1):
            print(random.choice(Spec_Char))
  

Я ожидаю, что результат будет в окне графического интерфейса, там будет сгенерированный пароль. Он появляется в терминале, но не в окне. Когда это происходит путем внесения изменений в output.pack(), он просто перечисляет случайные числа и имя функции (например, 9012381generate)

Комментарии:

1. Вы должны return ввести пароль от своего generate() метода. print выведет его на консоль.

2. лучше внутри generate использовать self.output.config(text=) вместо print() — но сначала создайте одну строку со всеми буквами, а затем используйте self.output.config(text=)

Ответ №1:

Внутри generate вы должны создать строку с паролем и использовать self.output.config(text=password) вместо print() .

Я изменил код, потому что у меня это не сработало. Теперь каждый может скопировать код и запустить его.

 from tkinter import *
import random
import string

words = string.ascii_uppercase
numbers = string.digits
spec_char = '!@#$%'

class GenPass:

    def __init__(self, master):
        frame = Frame(master) # add parent for Frame
        frame.pack()

        self.printButton = Button(frame, text="Generate Password", padx=4, pady=4, command=self.generate)
        self.printButton.pack(side=LEFT)

        self.quitButton = Button(frame, text="Copy to Clipboard", padx=4, pady=4, command=master.destroy)
        self.quitButton.pack(side=LEFT)

        self.output = Label(master, fg="Green")
        self.output.pack()

        self.generate() # genrate password at start


    def generate(self):
        password = ''
        for i in range(3):
            password  = random.choice(words)
        for i in range(2):
            password  = random.choice(numbers)
        for i in range(1):
            password  = random.choice(spec_char)
        self.output.config(text=password)


root = Tk()
GenPass(root)
root.mainloop()
  

введите описание изображения здесь

Кстати: у каждого виджета должен быть родитель, поэтому я добавляю master в Frame() . Возможно, здесь нет никакой разницы, но если у вас будет много фреймов или виджетов, то виджет без родительского элемента может отображаться в неожиданном месте.

pack() и place() и grid() не следует смешивать в одном окне или фрейме, потому что pack() и grid() пытаются вычислить позицию динамически, и другой менеджер layour может создать проблему с этим. Но с помощью pack/grid/place вы можете поместить frame и внутри этого frame вы можете использовать другой layour manager ( pack/grid/place ).

Комментарии:

1. Спасибо! Возможно ли, что ‘words = string.asciii_uppercase’ на самом деле указывает на текстовый документ со словарными словами вместо этого?

2. да, вы можете использовать list() со словами. Используя dict() , вам пришлось бы использовать choice(words.values()) . И вы можете читать слова из файла — если у вас есть каждое слово в отдельной строке words = open(filename).read().split('n')

3. …и из python 3.6 вы можете использовать … docs.python.org/3.6/library/secrets.html