【问题标题】:Still struggling with class scope [closed]仍在与班级范围作斗争[关闭]
【发布时间】:2015-04-23 17:17:47
【问题描述】:

我还没有完全理解课程的范围。我已经阅读了这篇文章,并且我一直在尝试做不同的事情来取得一些成功,但这让我摸不着头脑。我正在玩这个代码。我认为 Bryan Oakley 可能已经写了这个例子,但不是正面的。

基本上,这是一个分页示例。我添加了 buttoncontroloff 和 buttoncontrolon 函数来尝试控制菜单按钮的状态。我在 Page1 类中尝试过,但没有成功。

class Page1(Page):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, MainMenu, *args, **kwargs)
        newframe = tk.Frame(self, width=780, height=540, background="red")
        newframe.place(anchor="c", relx=.5, rely=.5)
        main = MainView()
        main.buttoncontrolon()

我确实在开始时禁用了其中一个按钮,所以我有一部分。但是当我试图在两个班级之间这样做时,我无法弄清楚。当您单击第 2 页按钮时,我只想启用第 1 页按钮。

import Tkinter as tk
from Tkinter import *


class Page(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
    def show(self):
        self.lift()


class Page1(Page):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        newframe = tk.Frame(self, width=780, height=540, background="red")
        newframe.place(anchor="c", relx=.5, rely=.5)

class Page2(Page):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        newframe = tk.Frame(self, width=780, height=540, background="blue")
        newframe.place(anchor="c", relx=.5, rely=.5)


class MainView(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        p1 = Page1(self)
        p2 = Page2(self)

        buttonframe = tk.Frame(self)
        container = tk.Frame(self)
        buttonframe.pack(side="top", fill="x", expand=False)
        container.pack(side="top", fill="both", expand=True)

        p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)

        self.b1 = tk.Button(buttonframe, text="Page 1", command=lambda: p1.lift())
        self.b1.pack(side="left")
        self.b2 = tk.Button(buttonframe, text="Page 2", command=lambda: p2.lift())
        self.b2.pack(side="left")

        p1.show()

    def buttoncontroloff(self):
        self.b1.config(state = DISABLED)

    def buttoncontrolon(self):
        self.b1.config(state = NORMAL)

if __name__ == "__main__":
    root = tk.Tk()
    main = MainView(root)
    main.buttoncontroloff()
    main.pack(side="top", fill="both", expand=True)
    root.wm_geometry("800x600")
    root.mainloop()

【问题讨论】:

  • 对于 Python 中的 OOP,我想向您推荐 Mark Lutz 的 Learning Python,我发现它非常有帮助。
  • 我一直在浏览名为 Dive into Python 的在线书。
  • 这也是一本好书(我也读过 DivPython 的几章),Learning Python 解释了 OOPs using Attribute Inheritance Search Tree 无处不在,这真的很有帮助——告诉你 python 类作用域是如何工作的。 . 但是它教的很慢...试试看吧!
  • 无论你选择什么书和在线资源,我建议阅读 Python 3 的书(可能与 Python 2 有所不同)。

标签: python class scope


【解决方案1】:

我会这样做:在MainView 中编写一个方法来打开一个编号页面(0 ...):

def open_page(self, page_number):
    # enable all except the button for this page.
    for i, button in enumerate(self.buttons):
        if i == page_number:
            button.config(state=DISABLED)
        else:
            button.config(state=ACTIVE)

    self.pages[page_number].lift()

使按钮使用此方法传递页码,作为它们的命令:

self.b1 = tk.Button(buttonframe, 
    text="Page 1", command=lambda: self.open_page(0))
self.b2 = tk.Button(buttonframe, 
    text="Page 2", command=lambda: self.open_page(1))

然后让所有页面和按钮进入这些列表:

p1 = Page1(self)
p2 = Page2(self)
self.pages = [ p1, p2 ]

self.buttons = [ self.b1, self.b2 ]

请记住,列表使用从 0 开始的索引。现在这可以很容易地重构为拥有一个 add_page 来为页面创建一个按钮,并将两者都放入列表等中。

Pages 不需要关心Buttons 自己;这不是他们的职责范围,Buttons 不属于他们。

【讨论】:

  • 我修正了这一行... for i, button in enumerate(self.page_buttons): 只为 i, button in enumerate(self.buttons):
  • ENABLED 行的错误很奇怪。仍在尝试看看那是关于什么的。
  • 因为没有名为 ENABLED 的 Tkinter 变量。看,我没有看到你的答案;您需要在我的答案下发表评论,我才能看到任何通知。
  • NORMAL代替ENABLED,我记错了Tk
  • 它应该是活动的。我修好了。
【解决方案2】:

Antti,我修正了错误。下面的代码效果很好!我会将您的解决方案标记为已回答。再次非常感谢。

import Tkinter as tk
from Tkinter import *


class Page(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
    def show(self):
        self.lift()

class Page1(Page):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        newframe = tk.Frame(self, width=780, height=540, background="red")


class Page2(Page):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        newframe = tk.Frame(self, width=780, height=540, background="blue")
        newframe.place(anchor="c", relx=.5, rely=.5)


class MainView(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        p1 = Page1(self)
        p2 = Page2(self)
        self.pages = [ p1, p2 ]

        buttonframe = tk.Frame(self)
        container = tk.Frame(self)
        buttonframe.pack(side="top", fill="x", expand=False)
        container.pack(side="top", fill="both", expand=True)

        p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)

        self.b1 = tk.Button(buttonframe, text="Page 1", command=lambda: self.open_page(0))
        self.b2 = tk.Button(buttonframe, text="Page 2", command=lambda: self.open_page(1))
        self.b2.pack(side="left")
        self.b1.pack(side="left")
        self.buttons = [ self.b1, self.b2 ]

        p1.show()


    def open_page(self, page_number):
        # enable all except the button for this page.
        for i, button in enumerate(self.page_buttons):
            if i == page_number:
                button.config(state=DISABLED)
            else:
                button.config(state=ACTIVE)
        self.pages[page_number].lift()


if __name__ == "__main__":
    root = tk.Tk()
    main = MainView(root)
    #main.buttoncontroloff()
    main.pack(side="top", fill="both", expand=True)
    root.wm_geometry("800x600")
    root.mainloop()

【讨论】:

  • 这是一个非常明显的错误,你在哪里看到类中的任何属性page_buttons?我想它应该是按钮,您也会收到 ENABLED 错误
  • 还有ctlbuttons应该做什么?
  • Padraic,这是我尝试从原始代码中运行时留下的垃圾。
  • 删除不需要的垃圾
猜你喜欢
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
  • 2016-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多