tkinter:将键映射到其他字母/ ciphres

时间:2013-06-02 12:22:24

标签: python events tkinter

有没有办法将关键事件映射到其他字母。这是为了 将ciphres放入录入字段的便捷方式:

一个例子:我的笔记本电脑没有额外的键盘上的ciphres键, 但我经常不得不做数字输入。所以我认为这会很好 有一个改变ciphres字母的条目:

e -> 1
z -> 2
d -> 3
v -> 4
f -> 5
...

我尝试了很多东西:

  • 标签模拟一个条目,但事件有问题, 因为标签小部件不支持此事件。
  • 通过条目<Key>事件我无法更改条目中的输入。按下的e将始终显示在条目中。 (我使用了tkinter的传播验证方法!)。

3 个答案:

答案 0 :(得分:0)

我知道最简单的方法是使用您分配给条目小部件的字符串变量来拦截输入。您可以对这些变量执行的操作之一是在变量发生更改时执行函数或方法,并且可以使用该函数/方法来修改条目内容。这是一个简单的例子:

from Tkinter import *

class EntryHack(Frame):
    def __init__(self, root):
        self.root = root
        Frame.__init__(self, root)
        self.pack(side="left")
        self.entry = Entry(self, width=10)
        self.entry.pack(side="left")
        self.entry_var = StringVar()
        self.entry_var.trace_variable("w", self.changed)
        self.entry["textvariable"] = self.entry_var

    def changed(self, *args):
        """Intercept changes"""
        value = self.entry_var.get()
        changed = False
        frm = "zxcasdqwe"
        to = "123456789"
        if not value.isdigit():
            changed = True
            new = ""
            for char in value:
                if char.isdigit() or char not in frm:
                    new += char
                else:
                    new += to[frm.index(char)]
            value = new
        if changed:
            self.entry_var.set(value)

root = Tk()
app = EntryHack(root)
root.mainloop()

关于trace_variable赋值的好处是,当您在字段中键入内容时,将调用的函数/方法,但将不会在对变量进行手动更改时调用,从而避免无限循环。

答案 1 :(得分:0)

您尝试绑定到<Key>失败的原因可能是因为您在处理击键后未能执行return "break"

您可以为键盘上的任何键创建自己的绑定。例如,要更改“e”以执行任何操作,请执行self.entry.bind("<e>", ...)。然后,在绑定中,您可以插入任何您想要的内容。如果执行return "break",则将禁止对密钥的默认处理。

如果要在字典中设置映射,可以绑定到"<Key>"。这是一个简单的例子:

import Tkinter as tk

class Example(tk.Frame):
    map = {"e": "1",
           "z": "2",
           "v": "3",
           # ... and so on
           }

    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.entry = tk.Entry(self, width=20)
        self.entry.pack(side="top", fill="x")
        self.entry.bind("<Key>", self.keymap)

    def keymap(self, event):
        if event.char in self.map:
            self.entry.insert("insert", self.map[event.char])
            return "break"

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

答案 2 :(得分:0)

好我自己的解决方案......

感谢@Justin S Barrett和@Brian Oakley。

根据@Brian Oakley的暗示,我解决了我的问题:

class DigitEntry(Frame):
    mapping = {
        "o": "0",
        "e": "1",
        "z": "2",
        "d": "3",
        "v": "4",
        "f": "5",
        "s": "6",
        "i": "7",
        "a": "8",
        "n": "9",
        ",": ".",

        "0": "0",
        "1": "1",
        "2": "2",
        "3": "3",
        "4": "4",
        "5": "5",
        "6": "6",
        "7": "7",
        "8": "8",
        "9": "9",
        ".": "."
        }
    def __init__(self, *args, **kwargs):
        Frame.__init__(self, *args, **kwargs)
        self.entry = Entry(self, width=10)
        self.entry.pack(fill="x")

        self.entry.bind("<Key>", self.keymap)
        self.entry.bind("<FocusOut>", self.check)

    def check(self, event):
        """if checks are necessary
        """
        pass

    def keymap(self, event):
        """ do mappings, pass allowed inputs and block the rest.
        """
        if event.char in self.mapping:
            self.entry.insert("insert", self.mapping[event.char])
            return "break"
        elif event.keysym in ["BackSpace", "Tab"]:
            pass
        else:
            self.entry.insert("insert", "")
            return "break"


class PointsEntry(DigitEntry):
    def __init__(self, *args, **kwargs):
        DigitEntry.__init__(self, *args, **kwargs)

    def check(self, event):
        value = self.entry.get()

        if value.find(".") >= 0:
            if not (value[-1] == "." or value[-2:] == ".5"):
                err = value + " bad frac digit"
                self.entry.delete(0, "end")
                self.entry["bg"] = "red"
                self.entry.insert("insert", err)

            elif value[-1] == ".":
                self.entry.insert("insert", "5")
                if len(value) == 1:
                    self.entry.insert(0, "0")
                return "break"
相关问题