Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.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_Types_Tkinter_Contextmenu_Keyboard Shortcuts - Fatal编程技术网

Python 键盘快捷键绑定、弹出式上下文菜单和键入错误

Python 键盘快捷键绑定、弹出式上下文菜单和键入错误,python,types,tkinter,contextmenu,keyboard-shortcuts,Python,Types,Tkinter,Contextmenu,Keyboard Shortcuts,我总是觉得当我问一个关于stackoverflow的问题时就像答案一样。。。应该是。。。RTFM,即使我得到的每一个答案都是友好、耐心和接受的。经过一个下午的努力,我终于找到了答案。我想打开一个Tkinter,文本框和绑定键(键盘快捷键)以及一个菜单项,这样我就有了一个很好的弹出菜单(又称上下文菜单),就像窗口的记事本一样,你可以右键单击并查看 Cut Copy Paste ----- Select All 使用Ctrl+X、Ctrl+C、Ctrl+V和Ctrl+A作为键绑定(我还不知

我总是觉得当我问一个关于stackoverflow的问题时就像答案一样。。。应该是。。。RTFM,即使我得到的每一个答案都是友好、耐心和接受的。经过一个下午的努力,我终于找到了答案。我想打开一个Tkinter,文本框和绑定键(键盘快捷键)以及一个菜单项,这样我就有了一个很好的弹出菜单(又称上下文菜单),就像窗口的记事本一样,你可以右键单击并查看

Cut 
Copy 
Paste 
----- 
Select All
使用Ctrl+X、Ctrl+C、Ctrl+V和Ctrl+A作为键绑定(我还不知道如何执行撤消)。问题是我不能让键绑定和菜单弹出窗口都使用同一个函数。如果我在select_all()的定义中添加或删除“event”参数,一个有效,另一个无效

from Tkinter import *

# Clears the clipboard and copies the selected text to the it
def copy():
    mainwin.clipboard_clear()
    mainwin.clipboard_append(mainwin.selection_get())

# Needed for the right click pop-up menu to work, goes with copy()
def popup(event):
    popupmenu.post(event.x_root, event.y_root)

# Selects all text, used with the "control a" keybinding
def select_all(event):
    textbox.tag_add(SEL, "1.0", END)
    textbox.mark_set(INSERT, "1.0")
    textbox.see(INSERT)
    return 'break'

# Start of the program
mainwin = Tk()

scrollbar = Scrollbar(mainwin)
scrollbar.pack(side=RIGHT, fill=Y)

textbox = Text(mainwin, yscrollcommand=scrollbar.set)
textbox.pack(side=LEFT, fill=BOTH)

scrollbar.config(command=textbox.yview)

# Key bindings for the Text widget
textbox.bind("<Control-Key-a>", select_all)

# Pop-up menu, with right click binding for the Text widget
popupmenu = Menu(mainwin, tearoff=0)
popupmenu.add_command(label="Copy", command=copy)
popupmenu.add_separator()
popupmenu.add_command(label="Select All", command=select_all)
textbox.bind("<Button-3>", popup)

mainloop()

我可以只写两个函数,但这似乎真的很低效,也不能解释为什么程序会这样做

这里的问题是,当您将一个函数绑定到一个用户输入事件(如按键或鼠标单击)并用该事件调用它时,它会将该事件发送到该函数。这非常有用,因为您可能希望将鼠标单击的位置传递给一个函数,该函数应该在画布上绘制一个点。但是,如果单击或按键仅用作加速器,则传递的是一个无用的事件。这本身并不是那么糟糕,但是如果您还想不通过按键或鼠标单击(比如通过菜单中的命令)访问该功能,该怎么办?这不会发送事件,而您的函数需要一个事件

有多种方法可以解决这个问题

  • 使用
    def select_all(event=None)
    而不是
    def select_all(event)
    定义函数。这将允许您的函数预期0或1个参数,如果未向其传递参数,则默认为
    None
    事件。(谢谢,@Bryan。)

  • 使用
    def select_all(*event)
    而不是
    def select_all(event)
    定义函数。这将允许函数使用任意数量的位置参数,包括0或1。通用名称为
    *args
    ,或“星型args”

  • 使用
    popupmenu绑定菜单命令。添加命令(label=“Select All”,command=lambda:Select_All(0))
    。这定义了一个内联函数,该函数包括用一个参数调用
    select\u all
    函数。那个论点是垃圾,但你无论如何都没有使用它,所以一切都很好。我认为在
    tkinter
    中,您也可以使用
    command=select_all,0
    将命令与参数绑定,但是
    lambda
    结构更受欢迎,因为它在
    tkinter
    之外很有用,而且确实是一个方便学习的语言特性(例如,按每个项的第二个元素对iterable进行排序,排序方式为
    (mylist,key=lambda x:x[1])


  • 这里的问题是,当您将函数绑定到用户输入事件(如按键或鼠标单击)时然后用该事件调用它,它将事件发送到该函数。这是非常有用的,因为您可能希望将鼠标单击的位置传递给一个函数,该函数应该在画布上绘制一个点。但是,如果单击或按键仅用作加速器,那么您传递的是一个无用的事件。这还不错它本身,但是如果你也不想通过按键或鼠标点击来访问该功能,比如说,通过菜单中的命令来访问该功能呢?这不会发送事件,而你的功能需要一个事件

    有多种方法可以解决这个问题

  • 使用
    def select_all(event=None)
    而不是
    def select_all(event)
    定义函数。这将允许函数预期0或1个参数,如果没有参数传递给函数,则默认为
    None
    事件(谢谢@Bryan)

  • 使用
    def select_all(*event)
    而不是
    def select_all(event)
    定义函数。这将允许函数使用任意数量的位置参数,包括0或1。此函数的通用名称为
    *args
    或“星形args”

  • 使用
    popupmenu绑定菜单命令。添加_命令(label=“Select All”,command=lambda:Select_All(0))
    。这定义了一个内联函数,该函数包括使用一个参数调用
    select_all
    函数。该参数是垃圾,但您无论如何都不使用它,所以一切都很好。我认为在
    tkinter
    中,您还可以使用
    command=select_all,0
    参数绑定命令,但是
    lambda
    常量指令更受欢迎,因为它在
    tkinter
    之外很有用,而且确实是一种方便学习的语言功能(例如,通过
    排序(mylist,key=lambda x:x[1])按每个项的第二个元素对iterable进行排序。


  • 我认为
    event=None
    *event
    更惯用。我认为
    event=None
    *event
    更惯用
    TypeError: select_all() takes exactly 1 argument (0 given)