Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python tkinter中的可滚动帧类_Python_Python 3.x_Tkinter - Fatal编程技术网

Python tkinter中的可滚动帧类

Python tkinter中的可滚动帧类,python,python-3.x,tkinter,Python,Python 3.x,Tkinter,我在tkinter中实现了自己的可滚动框架类: class scrolledFrame(tk.Frame): def __init__(self, parent): tk.Frame.__init__(self, parent) self.canvas = tk.Canvas(self) self.canvas.pack(fill = "both", expand = True, side = "left&qu

我在tkinter中实现了自己的可滚动框架类:

class scrolledFrame(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.canvas = tk.Canvas(self)
        self.canvas.pack(fill = "both", expand = True, side = "left")
        self.scroll = tk.Scrollbar(self, command = self.canvas.yview)
        self.scroll.pack(side = "right", fill = "y")
        self.canvas.config(yscrollcommand = self.scroll.set)
        self.content = tk.Frame(self.canvas)
        self.content.bind("<Configure>", self.resizeCanvas)
        self.contentWindow = self.canvas.create_window((0,0), window = self.content, anchor = "nw")
        self.content.bind("<Enter>", self.enableScrollCanvas)
        self.content.bind("<Leave>", self.disableScrollCanvas)
    def scrollCanvas(self, event):
        self.canvas.yview_scroll(int(-1*(event.delta/120)), "units")
    def enableScrollCanvas(self, event):
        self.canvas.bind_all("<MouseWheel>", self.scrollCanvas)
    def disableScrollCanvas(self, event):
        self.canvas.unbind_all("<MouseWheel>")
    def resizeCanvas(self, event):
        self.update_idletasks()
        self.canvas.config(scrollregion = self.canvas.bbox("all"))
        self.canvas.itemconfig(self.contentWindow, width = self.canvas.winfo_width())

root = tk.Tk()
exampleFrame = scrolledFrame(root)
exampleFrame.pack()
exampleLabel = tk.Label(exampleFrame.content, text = "I'm in the scrolled frame!")
exampleLabel.pack()
root.mainloop()
类滚动帧(tk.Frame):
定义初始化(自身,父级):
tk.Frame.\uuuu init\uuuuu(自,父)
self.canvas=tk.canvas(self)
self.canvas.pack(fill=“both”,expand=True,side=“left”)
self.scroll=tk.Scrollbar(self,command=self.canvas.yview)
self.scroll.pack(side=“right”,fill=“y”)
self.canvas.config(yscrollcommand=self.scroll.set)
self.content=tk.Frame(self.canvas)
self.content.bind(“,self.resizeCanvas)
self.contentWindow=self.canvas.create_window((0,0),window=self.content,anchor=“nw”)
self.content.bind(“,self.enableCollCanvas)
self.content.bind(“,self.disableScrollCanvas)
def scrollCanvas(自我、事件):
self.canvas.yview_滚动条(int(-1*(event.delta/120)),“单位”)
def enableScrollCanvas(自我、事件):
self.canvas.bind_all(“,self.scrollCanvas)
def disableScrollCanvas(自身、事件):
self.canvas.unbind_all(“”)
def resizeCanvas(自身、事件):
self.update_idletasks()
self.canvas.config(scrollregion=self.canvas.bbox(“全部”))
self.canvas.itemconfig(self.contentWindow,width=self.canvas.winfo_width())
root=tk.tk()
exampleFrame=滚动帧(根)
例如frame.pack()
exampleLabel=tk.Label(exampleFrame.content,text=“我在滚动框中!”)
exampleLabel.pack()
root.mainloop()

这很好,但问题是要将小部件添加到滚动框中,父对象必须是
exampleFrame.content
。我看过其他几个例子,它们都有相同的局限性。是否可以将类配置为
exampleFrame
可以作为小部件的父级,而不是
exampleFrame.content
?提前感谢。

感谢@Novel帮助回答此问题。
通过向类中添加
\uuuu getattr\uuuu
方法,可以实现所需的行为。如果类继承自
tk.Frame
,因此该类已被删除,则此操作将不起作用。代码如下:

class scrolledFrame():
    def __init__(self, parent):
        self.wrapper = tk.Frame(parent)
        self.canvas = tk.Canvas(self.wrapper)
        self.canvas.pack(fill = "both", expand = True, side = "left")
        self.scroll = tk.Scrollbar(self.wrapper, command = self.canvas.yview)
        self.scroll.pack(side = "right", fill = "y")
        self.canvas.config(yscrollcommand = self.scroll.set)
        self.content = tk.Frame(self.canvas)
        self.content.bind("<Configure>", self.resizeCanvas)
        self.contentWindow = self.canvas.create_window((0,0), window = self.content, anchor = "nw")
        self.content.bind("<Enter>", self.enableScrollCanvas)
        self.content.bind("<Leave>", self.disableScrollCanvas)
        self.attrib = set(dir(tk.Widget))
    def __getattr__(self, item):
        if item in self.attrib:
            return getattr(self.wrapper, item)
        else:
            return getattr(self.content, item)
    def __str__(self):
        return str(self.wrapper)
    def scrollCanvas(self, event):
        self.canvas.yview_scroll(int(-1*(event.delta/120)), "units")
    def enableScrollCanvas(self, event):
        self.canvas.bind_all("<MouseWheel>", self.scrollCanvas)
    def disableScrollCanvas(self, event):
        self.canvas.unbind_all("<MouseWheel>")
    def resizeCanvas(self, event):
        self.update_idletasks()
        self.canvas.config(scrollregion = self.canvas.bbox("all"))
        self.canvas.itemconfig(self.contentWindow, width = self.canvas.winfo_width())
root = tk.Tk()
exampleFrame = scrolledFrame(root)
exampleFrame.pack()
exampleLabel = tk.Label(exampleFrame, text = "I'm in the scrolled frame!")
exampleLabel.pack()
root.mainloop()
class scrolledFrame():
定义初始化(自身,父级):
self.wrapper=tk.Frame(父级)
self.canvas=tk.canvas(self.wrapper)
self.canvas.pack(fill=“both”,expand=True,side=“left”)
self.scroll=tk.Scrollbar(self.wrapper,command=self.canvas.yview)
self.scroll.pack(side=“right”,fill=“y”)
self.canvas.config(yscrollcommand=self.scroll.set)
self.content=tk.Frame(self.canvas)
self.content.bind(“,self.resizeCanvas)
self.contentWindow=self.canvas.create_window((0,0),window=self.content,anchor=“nw”)
self.content.bind(“,self.enableCollCanvas)
self.content.bind(“,self.disableScrollCanvas)
self.attrib=set(dir(tk.Widget))
def _uGetAttr _;(自身,项目):
如果项目在self.attrib中:
return getattr(self.wrapper,item)
其他:
return getattr(self.content,item)
定义(自我):
返回str(self.wrapper)
def scrollCanvas(自我、事件):
self.canvas.yview_滚动条(int(-1*(event.delta/120)),“单位”)
def enableScrollCanvas(自我、事件):
self.canvas.bind_all(“,self.scrollCanvas)
def disableScrollCanvas(自身、事件):
self.canvas.unbind_all(“”)
def resizeCanvas(自身、事件):
self.update_idletasks()
self.canvas.config(scrollregion=self.canvas.bbox(“全部”))
self.canvas.itemconfig(self.contentWindow,width=self.canvas.winfo_width())
root=tk.tk()
exampleFrame=滚动帧(根)
例如frame.pack()
exampleLabel=tk.Label(exampleFrame,text=“我在滚动框中!”)
exampleLabel.pack()
root.mainloop()

如果你不介意一些小把戏,你可以模拟你想要的。不过这有点像黑客

诀窍在于,当您调用
tk.Frame.\uuuu init\uuuu
时,需要将画布作为父对象,使
self
成为内容框架。当然,要做到这一点,您必须首先创建画布,要创建画布,您必须创建外部框架

class scrolledFrame(tk.Frame):
    def __init__(self, parent):
        ...
        self.pack = self.outer.pack
        self.place = self.outer.place
        self.grid = self.outer.grid
它看起来像这样:

class scrolledFrame(tk.Frame):
    def __init__(self, parent):
        self.outer = tk.Frame(parent)
        self.canvas = tk.Canvas(self.outer)
        self.scroll = tk.Scrollbar(self.outer, command = self.canvas.yview)
        tk.Frame.__init__(self, self.canvas)
        self.contentWindow = self.canvas.create_window((0,0), window = self, anchor = "nw")
但是,当您执行上述操作并尝试在
Scrolled frame
的实例上调用
pack
place
grid
时,它会做错误的事情,因为该实例指向内部框架而不是外部框架

class scrolledFrame(tk.Frame):
    def __init__(self, parent):
        ...
        self.pack = self.outer.pack
        self.place = self.outer.place
        self.grid = self.outer.grid
这里有一个技巧:解决方案是将调用重定向到
pack
place
,以及
grid
到外部框架

class scrolledFrame(tk.Frame):
    def __init__(self, parent):
        ...
        self.pack = self.outer.pack
        self.place = self.outer.place
        self.grid = self.outer.grid
有了它,您可以随心所欲地使用
滚动框架
,只要在将其添加到布局时使用
打包
放置
、或
网格

exampleFrame = scrolledFrame(root)
exampleFrame.pack(fill="both", expand=True)
for i in range(100):
    exampleLabel = tk.Label(exampleFrame, text = f"I'm in the scrolled frame! ({i})")
    exampleLabel.pack()

这是一个完整的工作示例,不过为了简洁起见,我删除了mouseweel代码

import tkinter as tk

class scrolledFrame(tk.Frame):
    def __init__(self, parent):
        self.outer = tk.Frame(parent)
        self.canvas = tk.Canvas(self.outer)
        self.scroll = tk.Scrollbar(self.outer, command = self.canvas.yview)
        tk.Frame.__init__(self, self.canvas)
        self.contentWindow = self.canvas.create_window((0,0), window = self, anchor = "nw")

        self.canvas.pack(fill = "both", expand = True, side = "left")
        self.scroll.pack(side = "right", fill = "y")
        self.canvas.config(yscrollcommand = self.scroll.set)
        self.bind("<Configure>", self.resizeCanvas)

        self.pack = self.outer.pack
        self.place = self.outer.place
        self.grid = self.outer.grid

    def resizeCanvas(self, event):
        self.canvas.config(scrollregion = self.canvas.bbox("all"))
        self.canvas.itemconfig(self.contentWindow, width = self.canvas.winfo_width())

root = tk.Tk()
exampleFrame = scrolledFrame(root)
exampleFrame.pack(fill="both", expand=True)
for i in range(100):
    exampleLabel = tk.Label(exampleFrame, text = f"I'm in the scrolled frame! ({i})")
    exampleLabel.pack(fill="x")
root.mainloop()
将tkinter作为tk导入
类scrolledFrame(tk.Frame):
定义初始化(自身,父级):
self.outer=tk.Frame(父级)
self.canvas=tk.canvas(self.outer)
self.scroll=tk.Scrollbar(self.outer,command=self.canvas.yview)
tk.Frame.\uuuu init\uuuu(self,self.canvas)
self.contentWindow=self.canvas.create_window((0,0),window=self,anchor=“nw”)
self.canvas.pack(fill=“both”,expand=True,side=“left”)
self.scroll.pack(side=“right”,fill=“y”)
self.canvas.config(yscrollcommand=self.scroll.set)
self.bind(“,self.resizeCanvas)
self.pack=self.outer.pack
self.place=self.outer.place
self.grid=self.outer.grid
def resizeCanvas(自身、事件):
self.canvas.config(scrollregion=self.canvas.bbox(“全部”))
self.canvas.itemconfig(self.contentWindow,width=self.canvas.winfo_width())
root=tk.tk()
exampleFrame=滚动帧(根)
exampleFrame.pack(fill=“both”,expand=True)
对于范围(100)内的i:
exampleLabel=tk.Label(