#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()
метода.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