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")

运行再次程序,确认还是没有排版问题

看到这是怎么回事了吗?一次只解决一个问题。分节组织代码。将所有布局命令集中在一个地方,这样您就可以更好地可视化组合在一起的小部件。