【问题标题】:Frame not loading with tkinter框架未使用 tkinter 加载
【发布时间】:2017-04-18 13:14:00
【问题描述】:

我正在尝试在 python3 中使用tkinter 编写一个非常简单的游戏。这是一个连续的游戏,玩了很多个时期。我的问题是,在一个周期结束时,单击“下一个周期”按钮时,下一个周期没有加载。这是我的代码:

import tkinter as tk
from tkinter import ttk

class Game(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)

        container = tk.Frame(self)
        container.pack(side='top', fill='both', expand=True)

        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        F=Period
        frame = F(container, self)
        self.frames[F] = frame
        frame.grid(row=0, column=0, sticky='nsew')

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()

class Period(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)

        firstOffer = 5

        labelOffer = tk.Label(self, anchor='center', text=str(firstOffer))
        labelOffer.place(anchor='center', relx=0.6, rely=0.5)  

        buttonAcc = ttk.Button(self, text='Accept', command=lambda: self.PeriodSummary(parent, controller))
        buttonAcc.place(anchor='center', relx=0.35, rely=0.5)           

    def PeriodSummary(self, parent, controller):

        buttonNextPeriod = ttk.Button(self, text='Next Period', command=lambda: controller.show_frame(Period))
        buttonNextPeriod.place(anchor='center', relx=0.5, rely=0.75, width=200, height=80)          

app = Game()
app.wm_state('zoomed')
app.mainloop()

从代码运行时可以看出,当用户点击“下一个周期”时,没有任何反应。我希望它开始一个新的时期。我相信我对 Python 中的面向对象编程的理解不正确。任何指点将不胜感激,谢谢。

【问题讨论】:

  • 你做了什么来调试这个?您是否确认正在调用 show_frame 方法?如果您删除 lambda 并使用自定义函数,这会更容易。然后,您可以更轻松地添加打印功能或使用调试器停止。
  • 谢谢@BryanOakley。我只是按照你的建议做了(在show_frame 函数中添加了一个小的print 语句。确实,show_frame 没有被调用。但我看不出如果单击按钮不会调用它的原因。
  • 你真的需要 numpy 来复制这个问题吗?如果没有,你需要把它浓缩成不依赖于 numpy 的东西。
  • 我建议您阅读google.com/search?q=mcve&ie=utf-8&oe=utf-8 并将您的代码减少到显示问题所需的最低限度。以后不要随便写这么多没有测试的代码。
  • 谢谢@TerryJanReedy。我已按照您的指示缩短了代码,删除了我感兴趣的问题不需要的代码行。

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


【解决方案1】:

与您上面的评论相反,将print(self.frames) 放入show_frame 表明show_frame 正在 被调用。由于self.frames 只有一项,{<class '__main__.Period'>: <__main__.Period object .!frame.!period>},并且单个 Period 对象已经可见,.tkraise 暴露了已经暴露的内容并且没有可见的变化。有两种方法可以增加活力。

简单的选择:制作一个周期帧,将其公开,然后让Next 按钮更改内容。如果可能,请这样做。

更难的选择:制作多个周期帧,一次全部或根据需要。每个都有明显不同的内容。暴露第一。然后让按钮暴露下一个。有两个子选项:将相同大小的网格(或打包或放置)框架堆叠在每个其他框架的顶部,然后举起您想要看到的框架;或者只对您想要查看的网格进行网格化,在进行切换时取消网格化。如果您需要重新曝光以前看到的帧,我只会走多帧路线。如果您需要,请使用选项卡式框架小部件,例如 ttk.Notebook,它会为您处理堆叠和曝光。一个例子是一个需要填写多个表单的窗口,每个表单都可能有多种用途。一个特别的例子是 IDLE 的选项卡式配置对话框。

【讨论】:

  • 谢谢@TerryJanReady。我不需要重新曝光以前看到的帧。我只想在单击按钮后按顺序查看句点。在我的代码中,Next 按钮确实指的是周期框架,所以我不明白为什么没有显示新的周期。我可以将类创建为 Period2、Period3 等。但这并不优雅,必须有更简单的方法。
  • 我会在新帖子中以更好的方式提出这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
  • 2020-01-22
  • 2015-11-26
  • 2019-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多