циклический просмотр списка клавиш - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь создать историю команд с помощью виджета ввода tkinter и клавиш со стрелками вверх / вниз. Это очень простой клиент 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, но я не могу точно увидеть, как это достигается.

Используя приведенный выше код, я могу привязать нажатие клавиши со стрелкой вверх к виджету «Ввод», а при нажатии он вставляет последнюю введенную команду. Если бы я продолжал нажимать клавишу со стрелкой вверх, я бы хотел, чтобы она продолжала циклически повторять последние введенные команды в списке.

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Вопрос : циклически переключать элементы в списке, нажимая 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

0 голосов
/ 25 января 2019

Это версия, не основанная на ООП.

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...