【问题标题】:How to create a new pages using classes in Tkinter?如何使用 Tkinter 中的类创建新页面?
【发布时间】:2019-04-11 09:11:32
【问题描述】:

我试图创建一个可以重叠每个页面Page 1, Page 2, Page 3 的 tkinter GUI。我在两个地方挣扎:

使用类而不是方法,所以我已将它们注释掉,但我尝试将类放在命令中的括号中,即command=(mainPage),但这会产生错误:

builtins.NameError: name 'mainPage' is not defined

我苦苦挣扎的第二个地方是不能重叠每个班级。

我的代码如下:

from tkinter import *

class testOverlap(Frame):

    def __init__(self, root):
        Frame.__init__(self, root)
        self.root = root

        self.topButtons()

        self.pageOne()
        self.pageTwo()
        self.pageThree()

    def topButtons(self):

        self.firstPage = Button(self.root, text="Go to Page 1", background="WHITE", height = 2, width = 16, command= self.pageOne())
        self.firstPage.place(x=0, y=0)

        self.secondPage = Button(self.root, text="Go to Page 2", background="WHITE",height = 2, width = 16, command= self.pageTwo())
        self.secondPage.place(x=121, y=0)

        self.thirdPage = Button(self.root, text="Go to Page 3", background="WHITE",height = 2, width = 17, command= self.pageThree())
        self.thirdPage.place(x=242, y=0)

#class mainPage(Frame):
    def pageOne(self):
        self.Label1 = Label(self.root, text=" First Page ", height = 20, width = 52, background="Green")
        self.Label1.place(x=0, y=40)

#class middlePage(Frame):
    def pageTwo(self):
        self.Label2 = Label(self.root, text=" Second Page ", height = 20, width = 52, background="Blue")
        self.Label2.place(x=0, y=40)

#class finalPage(Frame):
    def pageThree(self):
        self.Label3 = Label(self.root, text=" Third Page ", height = 20, width = 52, background="Red")
        self.Label3.place(x=0, y=40)

def main():
    root = Tk()
    root.title("Tk")
    root.geometry('370x340')
    app = testOverlap(root)
    root.mainloop()


if __name__ == '__main__':
    main()

【问题讨论】:

  • “使用类而不是方法,所以我将它们注释掉了” - 这没有任何意义。如果它们被注释掉,你就在使用类。您正在使用类解决问题吗?如果不是,我建议删除注释的代码,因为它在编写时非常混乱。
  • 我把它们注释掉了,因为如果我把它留在里面,它会被归类为非功能代码,但我会在以后尝试重新迭代。
  • 问题是,删除类完全改变了类语句下代码的性质。

标签: python python-3.x class user-interface tkinter


【解决方案1】:

创建框架(页面)和提升它(将其带到顶部以查看它)是 2 个完全不同的操作。要创建它,您需要在类实例上使用类似grid 的布局,并且要提升它,您需要使用实例的tkraise 方法。我们通常通过专门一个类来处理所有页面来做到这一点。试试这个:

from tkinter import *

class Controller(Frame):
    def __init__(self, root):
        Frame.__init__(self, root)

        self.pageOne = mainPage(self)
        self.pageOne.grid(row=0, column=0, sticky='nsew')
        self.pageTwo = middlePage(self)
        self.pageTwo.grid(row=0, column=0, sticky='nsew')
        self.pageThree = finalPage(self)
        self.pageThree.grid(row=0, column=0, sticky='nsew')
        self.menu = testOverlap(self)
        self.menu.grid(row=0, column=0, sticky='nsew')

        self.menu.tkraise() # show the testOverlap Frame now

class testOverlap(Frame):
    def __init__(self, root):
        Frame.__init__(self, root)
        self.topButtons()

    def topButtons(self):
        self.firstPage = Button(self, text="Go to Page 1", background="WHITE", height = 2, width = 16, command= self.master.pageOne.tkraise)
        self.firstPage.grid(row=0, column=0)

        self.secondPage = Button(self, text="Go to Page 2", background="WHITE",height = 2, width = 16, command= self.master.pageTwo.tkraise)
        self.secondPage.grid(row=0, column=1)

        self.thirdPage = Button(self, text="Go to Page 3", background="WHITE",height = 2, width = 17, command= self.master.pageThree.tkraise)
        self.thirdPage.grid(row=0, column=2)

class mainPage(Frame):
    def __init__(self, root):
        Frame.__init__(self, root)
        self.Label1 = Label(self, text=" First Page ", height = 20, width = 52, background="Green")
        self.Label1.grid()

class middlePage(Frame):
    def __init__(self, root):
        Frame.__init__(self, root)
        self.Label2 = Label(self, text=" Second Page ", height = 20, width = 52, background="Blue")
        self.Label2.grid()

class finalPage(Frame):
    def __init__(self, root):
        Frame.__init__(self, root)
        self.Label3 = Label(self, text=" Third Page ", height = 20, width = 52, background="Red")
        self.Label3.grid()

def main():
    root = Tk()
    root.title("Tk")
    root.geometry('370x340')
    app = Controller(root)
    app.pack(expand=True, fill=BOTH)
    root.mainloop()

if __name__ == '__main__':
    main()

还请注意,我删除了您对 place 的使用。如果可以的话,我建议你远离这个地方,改用gridpack。使用 place 需要在许多其他地方指定确切的大小,而 grid 或 pack 可以为您处理。

【讨论】:

  • 你建议我什么时候可以使用 place,如果你有链接,我可以阅读这些错误吗?我是 python 新手,但这对我很有帮助,我现在要研究这段代码并将其与我的问题进行比较。
  • 我认为说place 会导致奇怪的错误是不公平的。 place 完全是确定性的,没有错误。它导致的唯一问题是,如果您希望您的 UI 响应迅速且易于维护,则需要您做更多的工作。
  • place 仅应在需要部分覆盖其他小部件的浮动小部件时使用。它要求用户定义所有尺寸,所以忘记一个会使整个事情不起作用(如果你在上面的代码中用 place 替换 grid 会发生这种情况),或者它会使事情出现在屏幕外,使用新字体/python 版本/计算机.现在忘记那个地方的存在,让 tkinter 来做艰苦的工作。
  • 不,这不一定是正确的,地方只适用于浮动小部件。 place 当您想要将小部件堆叠在一起时实际上非常好。它还有其他用途。 place 实际上非常强大和灵活。我不建议在大多数工作中使用它,尤其是不建议初学者使用它,但它绝对适用于更多的东西,而不仅仅是浮动小部件。
  • @BryanOakley 我编辑了错误的评论,我同意这暗示 tkinter 而不是用户有问题。但我不同意你的其他评论;我还没有找到任何其他使用网格无法更轻松、更整洁地解决的地方。 (思维浮动小部件是一个非常重要的角色;我并不是主张永远不要使用地点。)
猜你喜欢
  • 2018-08-23
  • 1970-01-01
  • 2013-01-12
  • 2022-11-24
  • 1970-01-01
  • 2017-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多