Python Tkinter:如何使用箭头键滚动整个画布?

Python Tkinter:如何使用箭头键滚动整个画布?,python,tkinter,tkinter-canvas,Python,Tkinter,Tkinter Canvas,我正在编写一个python应用程序,它使用Tkinter,它的画布用于从托盘绘制图表。图表可能会变得相当大,我目前正在使用鼠标按钮press-1按住并拖动整个画布 我很难理解如何通过使用键盘上下左右的箭头键来实现整个画布的滚动 救命啊 画布的xview和yview方法用于滚动画布。这些方法与将滚动条连接到画布时使用的方法完全相同。您可以按单位或页面滚动。单位由画布选项XSCROLINCREMENT和YSCROLINCREMENT定义 要绑定到的事件有,和 将其放在一起,您将创建如下所示的绑定:

我正在编写一个python应用程序,它使用Tkinter,它的画布用于从托盘绘制图表。图表可能会变得相当大,我目前正在使用鼠标按钮press-1按住并拖动整个画布

我很难理解如何通过使用键盘上下左右的箭头键来实现整个画布的滚动

救命啊

画布的xview和yview方法用于滚动画布。这些方法与将滚动条连接到画布时使用的方法完全相同。您可以按单位或页面滚动。单位由画布选项XSCROLINCREMENT和YSCROLINCREMENT定义

要绑定到的事件有,和

将其放在一起,您将创建如下所示的绑定:

self.canvas.bind("<Left>",  lambda event: self.canvas.xview_scroll(-1, "units"))
self.canvas.bind("<Right>", lambda event: self.canvas.xview_scroll( 1, "units"))
self.canvas.bind("<Up>",    lambda event: self.canvas.yview_scroll(-1, "units"))
self.canvas.bind("<Down>",  lambda event: self.canvas.yview_scroll( 1, "units"))
您需要确保画布具有焦点。您可以显式地为其提供焦点,但您可能还希望通过单击鼠标为画布提供焦点:

self.canvas.focus_set()
self.canvas.bind("<1>", lambda event: self.canvas.focus_set())
下面是一个完整的工作示例:

import Tkinter as tk
import random

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.canvas = tk.Canvas(self, background="bisque")
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.hsb = tk.Scrollbar(self, orient="horizontal", command=self.canvas.xview)
        self.canvas.configure(xscrollcommand=self.hsb.set, yscrollcommand=self.vsb.set)

        self.canvas.grid(row=0, column=0, sticky="nsew")
        self.vsb.grid(row=0, column=1, sticky="ns")
        self.hsb.grid(row=1, column=0, sticky="ew")

        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        for i in range(100):
            x = random.randint(0, 1000)
            y = random.randint(0, 1000)
            width = random.randint(10, 50)
            height = random.randint(10, 50)
            fill = random.choice(("red", "orange", "yellow", "green", "blue", "violet"))
            self.canvas.create_rectangle(x, y, x+width, y+height, fill=fill)

        self.canvas.configure(scrollregion = self.canvas.bbox("all"))

        self.canvas.bind("<1>",     lambda event: self.canvas.focus_set())
        self.canvas.bind("<Left>",  lambda event: self.canvas.xview_scroll(-1, "units"))
        self.canvas.bind("<Right>", lambda event: self.canvas.xview_scroll( 1, "units"))
        self.canvas.bind("<Up>",    lambda event: self.canvas.yview_scroll(-1, "units"))
        self.canvas.bind("<Down>",  lambda event: self.canvas.yview_scroll( 1, "units"))

        self.canvas.focus_set()

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()
画布的xview和yview方法用于滚动画布。这些方法与将滚动条连接到画布时使用的方法完全相同。您可以按单位或页面滚动。单位由画布选项XSCROLINCREMENT和YSCROLINCREMENT定义

要绑定到的事件有,和

将其放在一起,您将创建如下所示的绑定:

self.canvas.bind("<Left>",  lambda event: self.canvas.xview_scroll(-1, "units"))
self.canvas.bind("<Right>", lambda event: self.canvas.xview_scroll( 1, "units"))
self.canvas.bind("<Up>",    lambda event: self.canvas.yview_scroll(-1, "units"))
self.canvas.bind("<Down>",  lambda event: self.canvas.yview_scroll( 1, "units"))
您需要确保画布具有焦点。您可以显式地为其提供焦点,但您可能还希望通过单击鼠标为画布提供焦点:

self.canvas.focus_set()
self.canvas.bind("<1>", lambda event: self.canvas.focus_set())
下面是一个完整的工作示例:

import Tkinter as tk
import random

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.canvas = tk.Canvas(self, background="bisque")
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.hsb = tk.Scrollbar(self, orient="horizontal", command=self.canvas.xview)
        self.canvas.configure(xscrollcommand=self.hsb.set, yscrollcommand=self.vsb.set)

        self.canvas.grid(row=0, column=0, sticky="nsew")
        self.vsb.grid(row=0, column=1, sticky="ns")
        self.hsb.grid(row=1, column=0, sticky="ew")

        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        for i in range(100):
            x = random.randint(0, 1000)
            y = random.randint(0, 1000)
            width = random.randint(10, 50)
            height = random.randint(10, 50)
            fill = random.choice(("red", "orange", "yellow", "green", "blue", "violet"))
            self.canvas.create_rectangle(x, y, x+width, y+height, fill=fill)

        self.canvas.configure(scrollregion = self.canvas.bbox("all"))

        self.canvas.bind("<1>",     lambda event: self.canvas.focus_set())
        self.canvas.bind("<Left>",  lambda event: self.canvas.xview_scroll(-1, "units"))
        self.canvas.bind("<Right>", lambda event: self.canvas.xview_scroll( 1, "units"))
        self.canvas.bind("<Up>",    lambda event: self.canvas.yview_scroll(-1, "units"))
        self.canvas.bind("<Down>",  lambda event: self.canvas.yview_scroll( 1, "units"))

        self.canvas.focus_set()

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

很好的解释。非常感谢。很好的解释。非常感谢。