from tkinter import *
class Interface_graphique(Frame):
def __init__(self, root, **kwargs):
Frame.__init__(self, root, width=768, height=576, **kwargs)
self.pack(fill=BOTH)
self.message_1 = Label(self, text="value1")
self.message_1.grid(row=0, sticky='w')
self.entry_1 = Entry(self)
self.entry_1.grid(row=0, column=1)
self.message_2 = Label(self, text="value2")
self.message_2.grid(row=1, sticky='w')
self.entry_2 = Entry(self)
self.entry_2.grid(row=1, column=1)
root = Tk()
interface = Interface_graphique(root)
interface.mainloop()
我想输入Entry小部件“ value1”,然后按向下箭头按钮将光标放在Entry小部件“ value2”中。有可能吗?
答案 0 :(得分:1)
您可以使用bind
和focus
:
绑定
Tkinter提供了一种强大的机制来让您处理事件 你自己对于每个小部件,您都可以绑定Python函数和方法 参加活动。
widget.bind(event, handler)
如果与事件描述匹配的事件发生在窗口小部件中,则 给定的处理程序将与一个描述事件的对象一起调用。
。
焦点
将输入焦点直接定位到此小部件。
widget.focus()
如果应用程序当前没有焦点,则此小部件将 如果应用程序通过窗口获得焦点,则获得焦点 经理。
from tkinter import *
class Interface_graphique(Frame):
def __init__(self, root, **kwargs):
Frame.__init__(self, root, width=768, height=576, **kwargs)
self.pack(fill=BOTH)
self.message_1 = Label(self, text="value1")
self.message_1.grid(row=0, sticky='w')
self.entry_1 = Entry(self)
self.entry_1.grid(row=0, column=1)
self.message_2 = Label(self, text="value2")
self.message_2.grid(row=1, sticky='w')
self.entry_2 = Entry(self)
self.entry_2.grid(row=1, column=1)
root.bind('<Down>', self.downKey)
root.bind('<Up>', self.upKey)
def downKey(self, event):
self.entry_2.focus()
def upKey(self, event):
self.entry_1.focus()
root = Tk()
interface = Interface_graphique(root)
interface.mainloop()
答案 1 :(得分:1)
简而言之,创建一个绑定,将焦点移动到所需位置。有很多方法可以做到这一点。如果只有两个小部件,则可以对这些小部件进行硬编码。但是,使用tkinter可以很容易地提供一个通用的解决方案,该解决方案始终可以在每个条目小部件中使用。
创建绑定时,绑定函数将接收一个表示事件的对象。该对象的属性之一是捕获事件的小部件。该小部件具有名为tk_focusNext
的方法,该方法将按标准焦点顺序返回下一个小部件。
您可以为使用此功能更改焦点的所有Entry小部件添加绑定。在下面的示例中,我们将向下箭头绑定到Entry
小部件类,以调用用于移动焦点的函数
首先,创建一个可以绑定到事件的方法:
def next_widget(self, event):
event.widget.tk_focusNext().focus()
return "break"
接下来,使用它绑定到每个条目小部件:
root.bind_class("Entry", "<Down>", self.next_widget)
或,绑定到每个单独的条目小部件:
self.entry_1.bind("<Down>", self.next_widget)
self.entry_2.bind("<Down>", self.next_widget)
答案 2 :(得分:-1)
一种解决方案是使用列表存储您的输入字段,然后根据索引将每个字段与对列表中上一个和下一个字段的引用绑定起来。
下面的代码将根据需要工作,并且具有仅在输入字段内工作时才能带来的额外好处。当输入字段的焦点完全与您的GUI混淆时,您不必担心使用箭头键。
import tkinter as tk
root = tk.Tk()
entry_list = []
def move_entry(x):
entry_list[x].focus()
for i in range(5):
entry_list.append(tk.Entry(root))
entry_list[-1].pack()
if i == 0:
entry_list[-1].bind('<Down>', lambda e, x=i: move_entry(x + 1))
elif i == 4:
entry_list[-1].bind('<Up>', lambda e, x=i: move_entry(x - 1))
else:
entry_list[-1].bind('<Up>', lambda e, x=i: move_entry(x - 1))
entry_list[-1].bind('<Down>', lambda e, x=i: move_entry(x + 1))
root.mainloop()
正如布莱恩(Bryan)指出的,ctypes
有点矫kill过正,但我想把这个留给对ctypes
好奇的人一样。
您可以使用ctypes
来执行键盘事件,我复制了一个众所周知的ctypes
结构,并制作了一个简单的tkinter GUI来说明如何将上下箭头键绑定为类似于选项卡的功能。 / p>
如果您有任何疑问,请告诉我。
import tkinter as tk
import ctypes
from ctypes import wintypes
import time
user32 = ctypes.WinDLL('user32', use_last_error=True)
INPUT_MOUSE = 0
INPUT_KEYBOARD = 1
INPUT_HARDWARE = 2
KEYEVENTF_EXTENDEDKEY = 0x0001
KEYEVENTF_KEYUP = 0x0002
KEYEVENTF_UNICODE = 0x0004
KEYEVENTF_SCANCODE = 0x0008
MAPVK_VK_TO_VSC = 0
# msdn.microsoft.com/en-us/library/dd375731
VK_TAB = 0x09
VK_SHIFT = 0x10
# C struct definitions
wintypes.ULONG_PTR = wintypes.WPARAM
class MOUSEINPUT(ctypes.Structure):
_fields_ = (("dx", wintypes.LONG),
("dy", wintypes.LONG),
("mouseData", wintypes.DWORD),
("dwFlags", wintypes.DWORD),
("time", wintypes.DWORD),
("dwExtraInfo", wintypes.ULONG_PTR))
class KEYBDINPUT(ctypes.Structure):
_fields_ = (("wVk", wintypes.WORD),
("wScan", wintypes.WORD),
("dwFlags", wintypes.DWORD),
("time", wintypes.DWORD),
("dwExtraInfo", wintypes.ULONG_PTR))
def __init__(self, *args, **kwds):
super(KEYBDINPUT, self).__init__(*args, **kwds)
# some programs use the scan code even if KEYEVENTF_SCANCODE
# isn't set in dwFflags, so attempt to map the correct code.
if not self.dwFlags & KEYEVENTF_UNICODE:
self.wScan = user32.MapVirtualKeyExW(self.wVk,
MAPVK_VK_TO_VSC, 0)
class HARDWAREINPUT(ctypes.Structure):
_fields_ = (("uMsg", wintypes.DWORD),
("wParamL", wintypes.WORD),
("wParamH", wintypes.WORD))
class INPUT(ctypes.Structure):
class _INPUT(ctypes.Union):
_fields_ = (("ki", KEYBDINPUT),
("mi", MOUSEINPUT),
("hi", HARDWAREINPUT))
_anonymous_ = ("_input",)
_fields_ = (("type", wintypes.DWORD),
("_input", _INPUT))
LPINPUT = ctypes.POINTER(INPUT)
def _check_count(result, func, args):
if result == 0:
raise ctypes.WinError(ctypes.get_last_error())
return args
user32.SendInput.errcheck = _check_count
user32.SendInput.argtypes = (wintypes.UINT, # nInputs
LPINPUT, # pInputs
ctypes.c_int) # cbSize
# Functions
def PressKey(hexKeyCode):
x = INPUT(type=INPUT_KEYBOARD,
ki=KEYBDINPUT(wVk=hexKeyCode))
user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
def ReleaseKey(hexKeyCode):
x = INPUT(type=INPUT_KEYBOARD,
ki=KEYBDINPUT(wVk=hexKeyCode,
dwFlags=KEYEVENTF_KEYUP))
user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
root = tk.Tk()
def up_key(event):
PressKey(VK_SHIFT)
PressKey(VK_TAB)
ReleaseKey(VK_TAB)
ReleaseKey(VK_SHIFT)
def down_key(event):
PressKey(VK_TAB)
ReleaseKey(VK_TAB)
tk.Entry(root).pack()
tk.Entry(root).pack()
tk.Entry(root).pack()
tk.Entry(root).pack()
tk.Entry(root).pack()
root.bind('<Up>', up_key)
root.bind('<Down>', down_key)
root.mainloop()