tkinter通过按键循环遍历列表

时间:2019-01-25 06:40:23

标签: python tkinter

我正在尝试使用tkinter Entry小部件和向上/向下箭头键创建命令历史记录。我想在业余时间想出一个非常基本的MUD客户。

# The list that hold the last entered commands.
self.previousCommands = []

# Binding the up arrow key to the Entry widget.
self.view.Tabs.tab1.E.bind('<Up>', self.checkCommandHistory)

# The function that should cycle through the commands.
def checkCommandHistory(self, event):
    comm = self.previousCommands[-1]
    self.view.Tabs.tab1.E.delete(0, END)
    self.view.Tabs.tab1.E.insert(0, comm)

基本上,我要使用向上和向下箭头键循环显示包含最后输入命令历史的列表。这种行为在大多数MUD客户端中都很常见,但我无法确切地知道如何实现。

使用上面的代码,我可以将向上箭头键绑定到Entry小部件,并在按下时确实插入了最后输入的命令。如果我要一直按向上箭头键,则希望它继续循环显示列表中最后输入的命令。

2 个答案:

答案 0 :(得分:2)

  

问题:通过按绑定到Up小部件的Down / Entry箭头键循环显示列表中的元素

创建从class object继承的tk.Entry

import tkinter as tk

class EntryHistory(tk.Entry):
    def __init__(self, parent, init_history=None):
        super().__init__(parent)
        self.bind('<Return>', self.add)
        self.bind('<Up>', self.up_down)
        self.bind('<Down>', self.up_down)

        self.history = []
        self.last_idx = None

        if init_history:
            for e in init_history:
                self.history.append(e)
            self.last_idx = len(self.history)

    def up_down(self, event):
        if not self.last_idx is None:
            self.delete(0, tk.END)

            if event.keysym == 'Up':
                if self.last_idx > 0:
                    self.last_idx -= 1
                else:
                    self.last_idx = len(self.history) -1
            elif event.keysym == 'Down':
                if self.last_idx < len(self.history) -1:
                    self.last_idx += 1
                else:
                    self.last_idx = 0

            self.insert(0, self.history[self.last_idx])

    def add(self, event):
        self.history.append(self.get())
        self.last_idx = len(self.history) - 1

if __name__ == "__main__":
    root = tk.Tk()
    entry = EntryHistory(root, init_history=['test 1', 'test 2', 'test 3'])
    entry.grid(row=0, column=0)
    root.mainloop()

使用Python测试:3.5

答案 1 :(得分:1)

这是基于非OOP的版本。

import tkinter as tk

root = tk.Tk()

history = []
history_index = -1

def runCommand(event):
    command = cmd.get()
    print("Running command: {}".format(command))
    cmd.set("")
    history.append(command)
    history_index = -1
    print(history)

def cycleHistory(event):
    global history_index
    if len(history):
        try:
            comm = history[history_index]
            history_index -= 1
        except IndexError:
            history_index = -1
            comm = history[history_index]
        cmd.set(comm)

cmd = tk.StringVar(root)
e = tk.Entry(root,textvariable=cmd)
e.grid()
e.bind("<Return>",runCommand)
e.bind("<Up>",cycleHistory)
e.focus()

root.mainloop()

基本上,您只需要保留一次用户下次按下向上箭头时应显示的历史记录。我使用history_index字段来执行此操作。 history_index最初设置为-1,每次访问时都将其递减1。

一旦没有更多历史记录可从列表中读取并从头开始,我将使用except IndexError异常将索引重置为-1。

按下返回键,运行命令,将其添加到历史记录中,并将索引重置为-1。