简体   繁体   English

Tkinter从右到左菜单

[英]Tkinter right to left menu

I am writing a GUI program using python with tkinter. 我正在使用python和tkinter编写GUI程序。 I want to put menu items from right to left. 我想从右到左放置菜单项。 is it possible? 可能吗? I tried grid, but I get Error 'it's a top-level window'. 我试过网格,但我得到错误'这是一个顶级窗口'。

import tkinter as tk
from tkinter import ttk
from tkinter import Menu
from tkinter import LEFT, RIGHT
from tkinter import W
menuBar = Menu(win)
win.config(menu=menuBar)
fileMenu = Menu(menuBar, tearoff=0).grid(sticky=W)
menuBar.add_cascade(label="File", menu=fileMenu)
fileMenu.add_command(label="New")

There is not a built in way to do this but you can try to work around it with event bindings. 没有内置的方法来执行此操作,但您可以尝试使用事件绑定来解决它。

My below example will use a few bindings to try and manage the location of a menu. 我的下面的示例将使用一些绑定来尝试和管理菜单的位置。

One thing we will need is a Toplevel() window to house the menu. 我们需要的一件事是Toplevel()窗口来容纳菜单。

Next we need to get rid of its buttons ( - , [] and X ). 接下来我们需要摆脱它的按钮( -[]X )。 This can be done with overidedirect(True) . 这可以通过overidedirect(True)

Now that we cannot manually move the Toplevel() window we need to bind the <Configure> event to a function that will position the top level on the right most side of our main window. 现在我们无法手动移动Toplevel()窗口,我们需要将<Configure>事件绑定到一个函数,该函数将顶层放在主窗口的最右侧。

Here is the binding: 这是绑定:

win.bind("<Configure>", lambda x: win.after(0, move_menu(x)))

Here is the function: 这是功能:

def move_menu(event):
    x = (win.winfo_width() - menu_frame.winfo_width())
    z = (win.winfo_x(), win.winfo_y())
    xx = menu_frame.winfo_width()
    menu_frame.geometry('%dx%d+%d+%d' % ((xx), 0, (z[0]+x+8), (z[1]+30)))

Next we will need to force the menu or rather the Toplevel window to stay on top of the main window. 接下来,我们需要强制菜单或者更确切地说Toplevel窗口保持在主窗口的顶部。 This can be done with menu_frame.attributes('-topmost', True) . 这可以通过menu_frame.attributes('-topmost', True) However we encounter an issue when you click outside of the man window and that is the toplevel menu window stays on top of all programs outside of your tkinter app. 但是,当您在man窗口外单击时,我们会遇到一个问题,即顶层菜单窗口位于您的tkinter应用程序之外的所有程序之上。

In order to manage this behavior we need another 2 bindings. 为了管理这种行为,我们需要另外2个绑定。 One for event '<Enter>' and one for event '<Leave>' . 一个用于事件'<Enter>' ,一个用于事件'<Leave>' This will allow us to toggle the overrideredirect() method when the mouse Enters and leaves the root window. 这将允许我们在鼠标进入并离开根窗口时切换overrideredirect()方法。

Here are the bindings: 这是绑定:

win.bind("<Enter>", lambda x: win.after(0, manage_top_attr(x, True)))
win.bind("<Leave>", lambda x: win.after(0, manage_top_attr(x, False)))

Here is the function: 这是功能:

def manage_top_attr(event, tf):
    menu_frame.attributes('-topmost', tf)

With all that added to the program we can have a menu that sits on the right of the screen. 通过添加到程序中的所有内容,我们可以在屏幕右侧显示一个菜单。

Code example: 代码示例:

import tkinter as tk

win = tk.Tk()
win.minsize(200, 200)
win.geometry("250x200")
menu_frame = tk.Toplevel(win)
menu_frame.overrideredirect(True)
menu_frame.attributes('-topmost', True)
tk.Label(win, text="").grid(row=0, column=0)

main_window_frame = tk.Frame(win)
main_window_frame.grid(row=1, column=0, sticky="nsew")

def manage_top_attr(event, tf):
    menu_frame.attributes('-topmost', tf)

def move_menu(event):
    print (event)
    x = (win.winfo_width() - menu_frame.winfo_width())
    z = (win.winfo_x(), win.winfo_y())
    xx = menu_frame.winfo_width()
    menu_frame.geometry('%dx%d+%d+%d' % ((xx), 0, (z[0]+x+8), (z[1]+30)))

win.bind("<Configure>", lambda x: win.after(0, move_menu(x)))
win.bind("<Enter>", lambda x: win.after(0, manage_top_attr(x, True)))
win.bind("<Leave>", lambda x: win.after(0, manage_top_attr(x, False)))

tk.Label(main_window_frame, text="Main window").grid(row=0, column=0)

menuBar = tk.Menu(menu_frame)
menu_frame.config(menu=menuBar)
fileMenu = tk.Menu(menuBar, tearoff=0)
menuBar.add_cascade(label="File", menu=fileMenu)
fileMenu.add_command(label="New")
menuBar.add_cascade(label="Edit", menu=fileMenu)
menuBar.add_cascade(label="Options", menu=fileMenu)
menuBar.add_cascade(label="Help", menu=fileMenu)

win.mainloop()

Results: 结果:

在此输入图像描述

After you resize the window: 调整窗口大小后:

在此输入图像描述

Now it doesn't behave perfectly and could probably use some work but its a start. 现在它表现不佳并且可能会使用一些工作,但它是一个开始。

不,您无法从右到左在菜单上创建项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM