Что делать с tkinter.Меню tearoffcommand?

#python #tkinter #tkinter-menu

#python #tkinter #tkinter-menu

Вопрос:

У меня есть каскадный tkinter.Меню, которое я создаю с помощью tearoff= 1. Команде tearoffcommand передаются два аргумента:

  • имя окна меню (идентификатор окна родительского окна?), Которое представляет собой строку типа «.#!menu.#!menu#!menu3», и
  • имя оторванного окна меню (идентификатор окна корневого окна нового оторванного меню), которое представляет собой строку типа «.tearoff1».

Что я могу сделать с этой информацией? Вот что я хотел бы сделать: по умолчанию разорванное меню размещается в местоположении экрана (x = 0, y = 0), но я хотел бы разместить его в другом месте (x, y).

Как я могу это сделать?

Пример кода, который пытается использовать «nametowidget», как предложено:

 import tkinter as tk

class App:
    def __init__(self, root):
        menubar = tk.Menu(root)
        menuA = tk.Menu(menubar, tearoff=0)
        menuB = tk.Menu(menubar, tearoff=0)
        menuC = tk.Menu(menubar, tearoff=1, tearoffcommand=self.onTearoff)
        menuC.add_command(label="Menu Row1")
        menuC.add_command(label="Menu Row2")
        menuC.add_command(label="Menu Row3")
        menubar.add_cascade(label="MenuA", menu=menuA)
        menubar.add_cascade(label="MenuB", menu=menuB)
        menubar.add_cascade(label="MenuC", menu=menuC)
        self.menubar = menubar
        root.config(menu=menubar)
        root.geometry("300x200")

    def onTearoff(self, wParent, wMenu):
        print("onTearoff(%s, %s)" % (wParent, wMenu)) # wMenu = ".tearoff1"
        w = root.nametowidget(wMenu) # KeyError: 'tearoff1'
        w.geometry(" 50 50")

if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    root.mainloop()
  

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

1. root.nametowidget(X) (вы можете использовать любое окно или виджет вместо root ) превратит эти строки идентификаторов в реальные объекты Tkinter. Я бы предположил, что tearoff является экземпляром Toplevel , поэтому вы могли бы использовать .geometry() для его изменения положения.

2. Спасибо @jasonharper, но nametowidget выдает ошибку ключа; пожалуйста, смотрите пример кода, который я добавил выше.

3. Похоже, nametowidget работает только с виджетами, явно созданными на Python — в нем нет условий для создания объекта Python для представления виджета, который был создан непосредственно в Tk. Возможно, для этого есть какой-то обходной путь, но поскольку вы хотите выполнить только одну команду в tearoff, вероятно, было бы проще просто выполнить эквивалент через Tk. Попробуйте root.tk.call('wm', 'geometry', wMenu, " 50 50")

4. Ах, root.tk.call идеально подходит для моих нужд. Спасибо за помощь!