tkinter: кадр в Toplevel отображается в родительском - PullRequest
0 голосов
/ 23 октября 2018

В настоящее время у меня есть две проблемы с экземплярами Toplevel в Tkinter.

Первое и самое важное: я хочу отобразить всплывающее окно и поместить в него 2 кадра для лучшего расположения в сетке, но это не работаеткак я ожидаю, это сработает:

import tkinter


root = tkinter.Tk()
tkinter.Button(root, text="ABC").grid(column=0, row=0)
tkinter.Label(root, text="FOO").grid(column=1, row=1)

win = tkinter.Toplevel()
f1 = tkinter.Frame(win).grid(row=0, column=0)
f2 = tkinter.Frame(win).grid(row=1, column=1)
tkinter.Label(f1, text="FRAME 1").grid()
tkinter.Label(f2, text="FRAME 2").grid()

root.mainloop()

Я бы ожидал, что «FRAME 1» и «FRAME 2» будут размещены в окне Toplevel, но на самом деле они помещены в root.Как я могу это исправить?

Во-вторых, менее важно: всплывающее окно в приведенном выше коде появляется за корневым окном, а я хотел бы, чтобы оно располагалось перед root, как мне этого добиться?это?

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

При настройке вашего менеджера геометрии, будь то grid(), pack() или place(), и вам необходимо иметь возможность взаимодействовать с этим виджетом позже, вам нужно будет присвоить виджет переменной, а затем применить менеджер геометрии кновая строка с использованием этого имени переменной.Таким образом, ваша переменная будет иметь значение не None, а правильный виджет.Это происходит потому, что все менеджеры геометрии возвращают None.

Далее, причина, по которой ваши метки находятся на неправильных окнах, заключается в том, что когда ваши метки пытаются соединиться с f1 и f2, они не могут найтиправильный контейнер tkinter из-за значений None, поэтому он по умолчанию обращается к корневому окну tkinter, пытаясь разместить его на чем-либо.

Исправив проблемы None, вы также исправите проблему с меткой.

Чтобы решить вопрос о том, что ваше окно верхнего уровня не находится перед вашим корневым окном, есть несколько вещей, которые вы можете сделать.Основная причина, по которой это происходит, заключается в том, что ваш код генерирует верхний уровень на __init__, а не позже, с помощью кнопки или временного события.

Если вам действительно нужно, чтобы окно верхнего уровня открывалось одновременноВ качестве пользователя root вы можете использовать after() и функцию для этого, и она будет размещена сверху.Если вам не нужно это прямо при открытии окна, вы можете назначить команду кнопке для запуска функции, которая создает верхнее окно.

Вот пример с after():

import tkinter as tk


root = tk.Tk()

def create_top():
    win = tk.Toplevel(root)
    f1 = tk.Frame(win)
    f1.grid(row=0, column=0)
    f2 = tk.Frame(win)
    f2.grid(row=1, column=1)
    tk.Label(f1, text="FRAME 1").grid()
    tk.Label(f2, text="FRAME 2").grid()

tk.Button(root, text="ABC").grid(column=0, row=0)
tk.Label(root, text="FOO").grid(column=1, row=1)

root.after(10, create_top)
root.mainloop()

Вот пример с кнопкой:

import tkinter as tk


root = tk.Tk()

def create_top():
    win = tk.Toplevel(root)
    f1 = tk.Frame(win)
    f1.grid(row=0, column=0)
    f2 = tk.Frame(win)
    f2.grid(row=1, column=1)
    tk.Label(f1, text="FRAME 1").grid()
    tk.Label(f2, text="FRAME 2").grid()

tk.Button(root, text="ABC", command=create_top).grid(column=0, row=0)
tk.Label(root, text="FOO").grid(column=1, row=1)

root.mainloop()
0 голосов
/ 23 октября 2018

Вы устанавливаете свои кадры f1 и f2 на возвращаемое значение команды grid(), которое равно None, поэтому tkinter.Label(f1, text="FRAME 1").grid() не работает так, как вы ожидаете.

Попробуйтекак то так:

win = tkinter.Toplevel()
f1 = tkinter.Frame(win)
f1.grid(row=0, column=0)
tkinter.Label(f1, text="FRAME 1").grid()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...