Открытие окон верхнего уровня в tkinter

#python #tkinter

Вопрос:

Я пытаюсь открыть окно верхнего уровня с меткой вызова функции, но метка не отображается. Что я делаю не так? Грациас.

 from tkinter import * 
import tkinter.font as fonte


def open_top():   
    top = Toplevel(master)
    top.geometry("375x238 789 479")
    top.resizable(width=FALSE, height=FALSE)
    topFont = fonte.Font(family='Ubuntu', size=40)
    label = Label(top, text='world', borderwidth=2, relief="sunk", width=24)
    label.config(font = topFont, height=11, wraplength=350)
    label.grid(row = 0, column = 0, columnspan=1, rowspan=1, sticky=W E N S)
    master.update()

# creating main tkinter window
master = Tk()
master.geometry("374x340 790 100")
master.resizable(width=FALSE, height=FALSE)
myFont = fonte.Font(family='Monospace', size=25)
view = Label(master, text='helo', borderwidth=2, relief="sunk", width=10)
view.config(font = ('Monospace', 36), height=3)
view.grid(row = 4, column = 0, columnspan=2, rowspan=1, sticky=W E N S, padx=5, pady=5)

btn = Button(master, text ='toplevel', command = lambda: open_top())
btn.grid(row=6, column=0, columnspan=1, pady=4, padx=4)
btn = Button(master, text='Quit', command=master.destroy)
btn.grid(row=6, column=1, columnspan=1, pady=4, padx=4)

mainloop()
 

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

1. у вас есть две переменные с одинаковыми именами, как вы думаете, что это делает (делает ли это что-нибудь еще)? также это может быть просто command=open_top

2. Почему у вас есть height=11 ? Это не в пикселях, а в символах. Следовательно, метка находится где-то ниже, в правом углу верхнего уровня. Удалите top.resizable(width=FALSE, height=FALSE) и попробуйте сделать полноэкранный режим верхнего уровня.

3. @Matiiss Я думаю, что я слепа. Какие 2 переменные.

4. @TheLizzard btn , последние 6-2 строки имеют одно и то же имя переменной, но теперь, если подумать, это не должно повлиять на вызов функции

5. @Matiiss Я слепой. И да, это не приведет к вызову функции. Но это все равно плохая практика.

Ответ №1:

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

@TheLizzard упоминает: wraplength значение также выражено символами, и поскольку вы установили его равным 350, а ваш шрифт не такой уж маленький, он будет обертывать текст, когда огромная его часть находится вне окна (и, вполне возможно, даже вне экрана), поэтому с текущим значением это совершенно бесполезно. (это также совершенно бесполезно, если вы добавляете статический текст, потому что тогда вы можете просто добавить новую строку или sth, вариант использования будет, когда вы не знаете, какой длины текст, например, он был взят из пользовательского ввода)

Возможные исправления:

  • Удалите аргументы ширины и высоты (действительно самый простой):
 label = Label(top, text='world', borderwidth=2, relief="sunk")
label.config(font=topFont, wraplength=350)
 

Виджет также может быть настроен сразу, вам не нужно использовать его метод, подобный этому, для инициализации:

 label = Label(top, text='world', borderwidth=2, relief="sunk", font=topFont, wraplength=350)
 
  • Измените значения высоты и ширины (ширину действительно не обязательно использовать, особенно если вы используете wraplength аргумент):
 label = Label(top, text='world', borderwidth=2, relief="sunk", font=topFont, wraplength=350, height=1)
 
  • Используйте якорь (на самом деле это не такое уж большое исправление или что-то в этом роде, но позволит вам увидеть текст (до некоторой степени)):
 label.config(anchor='nw')
 

Несколько других вещей:

Важно (предложения)
я настоятельно не рекомендуем использовать подстановочный знак ( * ) при импорте что-то, вы должны либо импортировать то, что вам нужно, например, from module import Class1, func_1, var_2 и так далее, либо импортировать весь модуль: import module вы также можете использовать псевдоним: import module as md или sth, как это, дело в том, что не все импортное, если вы на самом деле знаете, что Вы делаете; наименование столкновения эту проблему.

Также: Я настоятельно рекомендую следовать руководству по стилю PEP 8 для кода Python. Имена функций и переменных должны быть в snake_case , имена классов в CapitalCase . Не оставляйте места, = если оно используется как часть аргумента ключевого слова ( func(arg='value') ), но используйте, если оно используется для присвоения значения ( variable = 'some value' ). Есть две пустые строки вокруг объявлений функций и классов.

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

1. Хороший ответ, но вы также можете упомянуть, что wraplength=350 в данном случае это бесполезно.

2. @TheLizzard добавил (вверху, после ссылки, на случай, если вы ее не видите)