Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 按下按钮时如何查看菜单?_Python_Windows_Tkinter_Tcl_Tk - Fatal编程技术网

Python 按下按钮时如何查看菜单?

Python 按下按钮时如何查看菜单?,python,windows,tkinter,tcl,tk,Python,Windows,Tkinter,Tcl,Tk,接下来,我尝试查看(与用鼠标左键单击时相同)一个菜单sub1,当按下按钮Test,但我无法查看。在以下代码中,按钮似乎冻结了GUI: import tkinter as tk root = tk.Tk() menubar = tk.Menu(root) sub1 = tk.Menu(menubar, tearoff=0) sub1.add_command(label="Item 1", command=lambda : print("item 1")) sub1.add_command(la

接下来,我尝试查看(与用鼠标左键单击时相同)一个菜单
sub1
,当按下按钮
Test
,但我无法查看。在以下代码中,按钮似乎冻结了GUI:

import tkinter as tk

root = tk.Tk()
menubar = tk.Menu(root)

sub1 = tk.Menu(menubar, tearoff=0)
sub1.add_command(label="Item 1", command=lambda : print("item 1"))
sub1.add_command(label="Item 2", command=lambda : print("item 2"))


menubar.add_cascade(menu=sub1, label="Sub1", underline=0)
root.config(menu=menubar)

def cb(*args):
    root.tk.call('::tk::TraverseToMenu', root, 'S')

tk.Button(root, text="Test", command=cb).pack()

root.mainloop()
我还尝试了
update\u idletasks()
,但没有成功。我怎样才能解决这个问题

尝试使用:

Windows7、Python 3.6、Tkinter 8.6


Tkinter按钮不应该那样工作这就是菜单按钮的作用。但是如果你要继续攻击一个按钮,你需要绑定到按钮上的事件,而不仅仅是使用命令回调(当按钮处于待命状态时,在按钮上释放鼠标按钮1时触发回调;当鼠标按钮1按下按钮时触发报警)

我建议改为使用menubutton()。这对于用户来说更容易,因为它被设计成按下时会显示一个菜单。

Trivia 这个技巧在X窗口系统(读作Unix)中有效,因为“Alt键控”是由
tk
本身通过
tk::TraverseToMenu
函数处理的,在这种情况下,它绑定到
all
bind标记

在您的情况下,
tk
检测到它在
Win
环境中工作,并将
tk::TraverseToMenu
功能仅绑定到
Menubutton
bind标记,因为在这种情况下,“Alt keying”由本机
Win
wm处理

所说的内容由
菜单中的源代码表示。tcl

if {[tk windowingsystem] eq "x11"} {
    bind all <Alt-KeyPress> {
    tk::TraverseToMenu %W %A
    }

    bind all <F10> {
    tk::FirstMenu %W
    }
} else {
    bind Menubutton <Alt-KeyPress> {
    tk::TraverseToMenu %W %A
    }

    bind Menubutton <F10> {
    tk::FirstMenu %W
    }
}

你的代码适合我(python3,Debian)。你在用什么操作系统?是吗?非常好,非常感谢你的回答!有一件事我不明白,为什么你定义函数而不是if/else,而不是用if/else定义函数?@Nae将依赖操作系统的东西(如导入)分开是一个品味问题,也是我的习惯问题。真正的问题是为什么tkinter生成的事件(如)没有效果,而行为却与预期一致。
import tkinter as tk

root = tk.Tk()

if root._windowingsystem == 'win32':
    import ctypes

    keybd_event = ctypes.windll.user32.keybd_event
    alt_key = 0x12
    key_up = 0x0002

    def traverse_to_menu(key=''):
        if key:
            ansi_key = ord(key.upper())
            #   press alt + key
            keybd_event(alt_key, 0, 0, 0)
            keybd_event(ansi_key, 0, 0, 0)

            #   release alt + key
            keybd_event(ansi_key, 0, key_up, 0)
            keybd_event(alt_key, 0, key_up, 0)

else:
    #   root._windowingsystem == 'x11'
    def traverse_to_menu(key=''):
        root.tk.call('tk::TraverseToMenu', root, key)

menubar = tk.Menu(root)

sub1 = tk.Menu(menubar, tearoff=0)
sub1.add_command(label='Item 1', command=lambda: print('item 1'))
sub1.add_command(label='Item 2', command=lambda: print('item 2'))

menubar.add_cascade(menu=sub1, label='Sub1', underline=0)
root.config(menu=menubar)

traverse_button = tk.Button(root, text='Test', command=lambda: traverse_to_menu('S'))
traverse_button.pack()

root.mainloop()