python 在 canvas 网格中绑定 tkinter 按钮并将滚动条添加到 canvas
python tkinter button binding in canvas grid and adding scrollbar to canvas
如何让滚动条显示在 canvas 上。
# python dashboard
import tkinter as tk
from tkinter import *
#======================{{{
class AutoScrollbar(Scrollbar):
def set(self, lo, hi):
if float(lo) <= 0.0 and float(hi) >= 1.0:
self.tk.call("grid", "remove", self)
else:
self.grid()
Scrollbar.set(self, lo, hi)
def pack(self, **kw):
raise TclError("cannot use pack with this widget")
def place(self, **kw):
raise TclError("cannot use place with this widget")
#====}}}
#===================={{{
class Dashboard():
def __init__(self, root):
self.root=root
root.title("Dashboard View")
canvasContainer = tk.Frame(root)
self.canvas=tk.Canvas(canvasContainer, width=1000, height=700,background='#002B36')
canvasContainer.grid(row=0,column=3)
frame = Frame(self.root, bd=2, relief=SUNKEN)
frame.grid(row=0,column=0, sticky="nw")
b1=Button(frame,text="Status", command=lambda color="#DC322F", filename="dashboard_content.txt" : self.contents(color,filename)).grid(row = 0,column = 0, sticky = "we")
b2=Button(frame,text="Processes", command=lambda color="#859900", filename="process.log" : self.contents(color,filename)).grid(row = 0,column = 1, sticky = "we")
b3=Button(frame,text="Links", command=lambda color="#B58900", filename="links.log" : self.contents(color,filename)).grid(row = 1,column = 0, sticky = "we")
b4=Button(frame,text="Traffic", command=lambda color="#268BD2", filename="version.log" : self.contents(color,filename)).grid(row = 1,column = 1, sticky = "we")
b5=Button(frame,text="App Version", command=lambda color="#D33682", filename="version.log" : self.contents(color,filename)).grid(row = 2,column = 0, sticky = "we")
b6=Button(frame,text="Archive/Purge", command=lambda color="#93A1A1", filename="cleanup.log" : self.contents(color,filename)).grid(row = 2,column = 1, sticky = "we")
# self.contents("blue","dashboard_content.txt")
# b1.bind("<ButtonPress-1>", lambda events, color="blue", filename="dashboard_content.txt" : self.contents(color,filename))
vsb = AutoScrollbar(canvasContainer,orient=VERTICAL)
hsb = AutoScrollbar(canvasContainer, orient=HORIZONTAL)
vsb.grid(row=0, column=2, sticky="ns")
hsb.grid(row=1, column=1, sticky="ew")
self.canvas.grid(row=0,column=1,sticky="news")
self.canvas.config(yscrollcommand=vsb.set, xscrollcommand=hsb.set, scrollregion=self.canvas.bbox("all"))
vsb.config(command=self.canvas.yview)
hsb.config(command=self.canvas.xview)
canvasContainer.grid_rowconfigure(0, weight=1)
canvasContainer.grid_columnconfigure(0, weight=1)
self.canvas.update_idletasks()
# Grid.columnconfigure(self.root,1,weight=1, minsize=100)
def contents(self, color="blue", filename="dashboard_content.txt"):
fhandle = open(filename)
lines = fhandle.read()
fhandle.close()
self.canvas.delete("all")
text1=self.canvas.create_text(0, 0, fill=color, anchor=NW)
self.canvas.itemconfig(text1, text=lines)
#===========}}}
if __name__== '__main__':
root=tk.Tk()
board=Dashboard(root)
root.mainloop()
如果我没有内容功能,就会出现滚动条。在这种情况下,如何在 canvas 周围设置滚动条。
您的代码中有几个问题。最大的问题是你试图一次解决太多问题。
如果您刚刚起步,则需要一次解决一个布局问题。看来您需要 GUI 中的两个主要区域——一个按钮面板和一个带有滚动条的 canvas。因此,首先创建两个框架,每个框架一个。给它们独特的颜色,这样你就可以看到什么是什么。在尝试任何其他操作之前确保这两个区域功能齐全 我的意思是,当您调整 window.
大小时确保它们适当调整大小
所以,从下面这个简单的程序开始吧。请注意,没有按钮,也没有 canvas。我们只是在创建 GUI 的基本脚手架。
import Tkinter as tk
class Dashboard():
def __init__(self, root):
self.root=root
root.title("Dashboard View")
# the width, height and colors are temporary,
# until we have more of the GUI working.
buttonPanel = tk.Frame(root, background="green", width=200, height=200)
canvasPanel = tk.Frame(root, background="pink", width=500, height=500)
# because these two panels are side-by-side, pack is the
# best choice:
buttonPanel.pack(side="left", fill="y")
canvasPanel.pack(side="right", fill="both", expand=True)
# fill in these two areas:
self._create_buttons(buttonPanel)
self._create_canvas(canvasPanel)
def _create_buttons(self, parent):
pass
def _create_canvas(self, parent):
pass
if __name__== '__main__':
root=tk.Tk()
board=Dashboard(root)
root.mainloop()
这是否符合您的预期?我假设是这样。现在,只要按钮在左边,canvas 和滚动条在右边,我们就不必再担心这两个区域相互影响了。
现在,创建 canvas:
def _create_canvas(self, parent):
self.canvas=tk.Canvas(parent, width=1000, height=700,background='#002B36')
vsb = tk.Scrollbar(parent, command=self.canvas.yview, orient="vertical")
hsb = tk.Scrollbar(parent, command=self.canvas.xview, orient="horizontal")
self.canvas.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
vsb.grid(row=0, column=0, sticky="ns")
hsb.grid(row=1, column=0, sticky="ew")
self.canvas.grid(row=0, column=1, sticky="nsew")
parent.grid_rowconfigure(0, weight=1)
parent.grid_columnconfigure(1, weight=1)
运行 程序又来了。你看到滚动条了吗?当您调整 window 的大小时,一切是否仍然正常工作?
下一步是添加按钮:
def _create_buttons(self, parent):
b1=tk.Button(parent,text="Status", command=lambda: self._contents("#DC322F", "dashboard_content.txt"))
b2=tk.Button(parent,text="Processes", command=lambda: self._contents("#859900", "process.log"))
b3=tk.Button(parent,text="Links", command=lambda: self._contents("#B58900", "links.log"))
b4=tk.Button(parent,text="Traffic", command=lambda: self._contents("#268BD2", "version.log"))
b5=tk.Button(parent,text="App Version", command=lambda: self._contents("#D33682", "version.log"))
b6=tk.Button(parent,text="Archive/Purge", command=lambda: self._contents("#93A1A1", "cleanup.log"))
b1.grid(row = 0,column = 0, sticky = "we")
b2.grid(row = 0,column = 1, sticky = "we")
b3.grid(row = 1,column = 0, sticky = "we")
b4.grid(row = 1,column = 1, sticky = "we")
b5.grid(row = 2,column = 0, sticky = "we")
b6.grid(row = 2,column = 1, sticky = "we")
运行再次程序,确认还是没有排版问题
看到这是怎么回事了吗?一次只解决一个问题。分节组织代码。将所有布局命令集中在一个地方,这样您就可以更好地可视化组合在一起的小部件。
如何让滚动条显示在 canvas 上。
# python dashboard
import tkinter as tk
from tkinter import *
#======================{{{
class AutoScrollbar(Scrollbar):
def set(self, lo, hi):
if float(lo) <= 0.0 and float(hi) >= 1.0:
self.tk.call("grid", "remove", self)
else:
self.grid()
Scrollbar.set(self, lo, hi)
def pack(self, **kw):
raise TclError("cannot use pack with this widget")
def place(self, **kw):
raise TclError("cannot use place with this widget")
#====}}}
#===================={{{
class Dashboard():
def __init__(self, root):
self.root=root
root.title("Dashboard View")
canvasContainer = tk.Frame(root)
self.canvas=tk.Canvas(canvasContainer, width=1000, height=700,background='#002B36')
canvasContainer.grid(row=0,column=3)
frame = Frame(self.root, bd=2, relief=SUNKEN)
frame.grid(row=0,column=0, sticky="nw")
b1=Button(frame,text="Status", command=lambda color="#DC322F", filename="dashboard_content.txt" : self.contents(color,filename)).grid(row = 0,column = 0, sticky = "we")
b2=Button(frame,text="Processes", command=lambda color="#859900", filename="process.log" : self.contents(color,filename)).grid(row = 0,column = 1, sticky = "we")
b3=Button(frame,text="Links", command=lambda color="#B58900", filename="links.log" : self.contents(color,filename)).grid(row = 1,column = 0, sticky = "we")
b4=Button(frame,text="Traffic", command=lambda color="#268BD2", filename="version.log" : self.contents(color,filename)).grid(row = 1,column = 1, sticky = "we")
b5=Button(frame,text="App Version", command=lambda color="#D33682", filename="version.log" : self.contents(color,filename)).grid(row = 2,column = 0, sticky = "we")
b6=Button(frame,text="Archive/Purge", command=lambda color="#93A1A1", filename="cleanup.log" : self.contents(color,filename)).grid(row = 2,column = 1, sticky = "we")
# self.contents("blue","dashboard_content.txt")
# b1.bind("<ButtonPress-1>", lambda events, color="blue", filename="dashboard_content.txt" : self.contents(color,filename))
vsb = AutoScrollbar(canvasContainer,orient=VERTICAL)
hsb = AutoScrollbar(canvasContainer, orient=HORIZONTAL)
vsb.grid(row=0, column=2, sticky="ns")
hsb.grid(row=1, column=1, sticky="ew")
self.canvas.grid(row=0,column=1,sticky="news")
self.canvas.config(yscrollcommand=vsb.set, xscrollcommand=hsb.set, scrollregion=self.canvas.bbox("all"))
vsb.config(command=self.canvas.yview)
hsb.config(command=self.canvas.xview)
canvasContainer.grid_rowconfigure(0, weight=1)
canvasContainer.grid_columnconfigure(0, weight=1)
self.canvas.update_idletasks()
# Grid.columnconfigure(self.root,1,weight=1, minsize=100)
def contents(self, color="blue", filename="dashboard_content.txt"):
fhandle = open(filename)
lines = fhandle.read()
fhandle.close()
self.canvas.delete("all")
text1=self.canvas.create_text(0, 0, fill=color, anchor=NW)
self.canvas.itemconfig(text1, text=lines)
#===========}}}
if __name__== '__main__':
root=tk.Tk()
board=Dashboard(root)
root.mainloop()
如果我没有内容功能,就会出现滚动条。在这种情况下,如何在 canvas 周围设置滚动条。
您的代码中有几个问题。最大的问题是你试图一次解决太多问题。
如果您刚刚起步,则需要一次解决一个布局问题。看来您需要 GUI 中的两个主要区域——一个按钮面板和一个带有滚动条的 canvas。因此,首先创建两个框架,每个框架一个。给它们独特的颜色,这样你就可以看到什么是什么。在尝试任何其他操作之前确保这两个区域功能齐全 我的意思是,当您调整 window.
大小时确保它们适当调整大小所以,从下面这个简单的程序开始吧。请注意,没有按钮,也没有 canvas。我们只是在创建 GUI 的基本脚手架。
import Tkinter as tk
class Dashboard():
def __init__(self, root):
self.root=root
root.title("Dashboard View")
# the width, height and colors are temporary,
# until we have more of the GUI working.
buttonPanel = tk.Frame(root, background="green", width=200, height=200)
canvasPanel = tk.Frame(root, background="pink", width=500, height=500)
# because these two panels are side-by-side, pack is the
# best choice:
buttonPanel.pack(side="left", fill="y")
canvasPanel.pack(side="right", fill="both", expand=True)
# fill in these two areas:
self._create_buttons(buttonPanel)
self._create_canvas(canvasPanel)
def _create_buttons(self, parent):
pass
def _create_canvas(self, parent):
pass
if __name__== '__main__':
root=tk.Tk()
board=Dashboard(root)
root.mainloop()
这是否符合您的预期?我假设是这样。现在,只要按钮在左边,canvas 和滚动条在右边,我们就不必再担心这两个区域相互影响了。
现在,创建 canvas:
def _create_canvas(self, parent):
self.canvas=tk.Canvas(parent, width=1000, height=700,background='#002B36')
vsb = tk.Scrollbar(parent, command=self.canvas.yview, orient="vertical")
hsb = tk.Scrollbar(parent, command=self.canvas.xview, orient="horizontal")
self.canvas.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
vsb.grid(row=0, column=0, sticky="ns")
hsb.grid(row=1, column=0, sticky="ew")
self.canvas.grid(row=0, column=1, sticky="nsew")
parent.grid_rowconfigure(0, weight=1)
parent.grid_columnconfigure(1, weight=1)
运行 程序又来了。你看到滚动条了吗?当您调整 window 的大小时,一切是否仍然正常工作?
下一步是添加按钮:
def _create_buttons(self, parent):
b1=tk.Button(parent,text="Status", command=lambda: self._contents("#DC322F", "dashboard_content.txt"))
b2=tk.Button(parent,text="Processes", command=lambda: self._contents("#859900", "process.log"))
b3=tk.Button(parent,text="Links", command=lambda: self._contents("#B58900", "links.log"))
b4=tk.Button(parent,text="Traffic", command=lambda: self._contents("#268BD2", "version.log"))
b5=tk.Button(parent,text="App Version", command=lambda: self._contents("#D33682", "version.log"))
b6=tk.Button(parent,text="Archive/Purge", command=lambda: self._contents("#93A1A1", "cleanup.log"))
b1.grid(row = 0,column = 0, sticky = "we")
b2.grid(row = 0,column = 1, sticky = "we")
b3.grid(row = 1,column = 0, sticky = "we")
b4.grid(row = 1,column = 1, sticky = "we")
b5.grid(row = 2,column = 0, sticky = "we")
b6.grid(row = 2,column = 1, sticky = "we")
运行再次程序,确认还是没有排版问题
看到这是怎么回事了吗?一次只解决一个问题。分节组织代码。将所有布局命令集中在一个地方,这样您就可以更好地可视化组合在一起的小部件。