Skip to main content
 首页 » 编程设计

python之如何使用 tkinter 将框架放在框架内

2025年05月04日16sky-heaven

我正在根据 70 年代和 80 年代 Avalon Hills 制作的策略游戏制作棒球程序,最后一部分是图形用户界面。我已经编写了运行游戏命令行的所有代码,而且我已经获得了使用图形用户界面选择阵容的代码。我设想一个 3by1 的网格,第一行有一个记分牌,一个显示结果、出局、本垒打、 double 等的文本框,最后一行在左侧分为投手卡和击球手卡,还有一个按钮框架。框架将在进攻和防守框架之间翻转。因此,首先防守框架提出了投球变化、改变位置和打球等选项。 Play ball 将框架更改为进攻选项,这将是捏击、捏跑、抢断等。但是我怎样才能将按钮放在一个框架内,然后将玩家卡片和按钮组合到另一个框架中,然后将其添加到主框架中呢?

DFrame 和 OFrame 类是内部类(因此是“elf”,而不是“self”)。我有 2 帧之间的动态切换。我的问题是打破了 DFrame 主循环,它只播放第一个的顶部,而 self.roadOuts 从不递增。这是我得到的:

while self.innings < 8.5 or self.homeScore == self.roadScore: 
    self.roadOuts = 0 
    while self.roadOuts < 3: 
        self.dFrame.mainloop() 
 
class DFrame(Frame): 
    def __init__(elf, parent): 
        Frame.__init__(elf) 
        elf._playButton = Button(elf, text = 'Play Ball', 
                                command = parent.oMenu) 
        elf._playButton.grid(row = 0, column = 0) 
        elf._pitchingButton = Button(elf, text = 'Pitching Change', 
                                command = parent.pitchingChange) 
        elf._pitchingButton.grid(row = 1, column = 0) 
        elf._positionButton = Button(elf, text = 'Defensive Substitution', 
                                command = parent.positionChange) 
        elf._positionButton.grid(row = 0, column = 1) 
        elf._alignButton = Button(elf, text = 'Change Positions', 
                                command = parent.positionSwap) 
        elf._alignButton.grid(row = 1, column = 1) 
        elf._doubleButton = Button(elf, text = 'Double Switch', 
                                command = parent.doubleSwitch) 
        elf._doubleButton.grid(row = 2, column = 0) 
        elf._walkButton = Button(elf, text = 'Intentional Walk', 
                                command = parent.intentionalWalk) 
        elf._walkButton.grid(row = 2, column = 1) 
        elf._depthButton = Button(elf, text = 'Change Infield Depth', 
                                command = parent.infieldDepth) 
        elf._depthButton.grid(row = 3, column = 0) 
 
class OFrame(Frame): 
    def __init__(elf, parent): 
        Frame.__init__(elf) 
        elf._playButton = Button(elf, text = 'Play Ball', 
                                command = parent.atBat) 
        elf._playButton.grid(row = 0, column = 0) 
        elf._pinchHitButton = Button(elf, text = 'Pinch Hit', 
                                command = parent.pinchHit) 
        elf._pinchHitButton.grid(row = 1, column = 0) 
        elf._prfButton = Button(elf, text = 'Pinch Run First', 
                                command = parent.pinchRunFirst) 
        elf._prfButton.grid(row = 0, column = 1) 
        elf._prsButton = Button(elf, text = 'Pinch Run Second', 
                                command = parent.pinchRunSecond) 
        elf._prsButton.grid(row = 1, column = 1) 
        elf._prtButton = Button(elf, text = 'Pinch Run Third', 
                                command = parent.pinchRunThird) 
        elf._prtButton.grid(row = 2, column = 1) 
        elf._stealButton = Button(elf, text = 'Steal', 
                                command = parent.steal) 
        elf._stealButton.grid(row = 2, column = 0) 
        elf._bunt4HitButton = Button(elf, text = 'Bunt for a hit', 
                                command = parent.bunt4AHit) 
        elf._bunt4HitButton.grid(row = 3, column = 0) 
        elf._hitNRunButton = Button(elf, text = 'Hit And Run', 
                                command = parent.hitAndRun) 
        elf._hitNRunButton.grid(row = 4, column = 0) 
        elf._sacButton = Button(elf, text = 'Sacrifice', 
                                command = parent.sacrifice) 
        elf._sacButton.grid(row = 4, column = 1) 
        elf._squeezeButton = Button(elf, text = 'Squeeze', 
                                command = parent.squeeze) 
        elf._squeezeButton.grid(row = 3, column = 1) 

下一个方法在 DFrame 的“play ball”按钮被点击时被调用,它使 OFrame.

def oMenu(self): 
    self.dFrame.grid_forget() 
    self.dFrame.destroy() 
    self.oFrame = self.OFrame(self) 
    self.oFrame.grid(row = 1, column = 1) 
    self.oFrame.mainloop() 

在击球结束时,我有:

self.oFrame.grid_forget() 
self.oFrame.destroy() 
self.dFrame = self.DFrame(self) 
self.dFrame.grid(row = 1, column = 1) 

请您参考如下方法:

我不确定我是否理解您的问题。看起来您知道如何将一个框架放在另一个框架中(这实际上与向框架添加按钮或任何其他小部件没有太大区别)。我认为您要问的是如何在任何给定时间动态切换正在显示的帧。

您可能需要 grid_forget 方法。使用 play_ball 按钮应该会导致 defense_frame 调用它的 grid_forget 方法,同时重新网格化 offense_frame。当然,如果您使用包几何管理器,这将是 pack_forget。

编辑

添加了您描述的网格布局的一个非常基本的工作示例。它可能会做得更好,但这应该让你开始。 (特别是 switchOffenseDefense 函数和 switch_button 按钮)。

import Tkinter as tk 
 
base=tk.Tk()  #this is the main frame 
root=tk.Frame(base)  #Really this is not necessary -- the other widgets could be attached to "base", but I've added it to demonstrate putting a frame in a frame. 
root.grid(row=0,column=0) 
scoreboard=tk.Frame(root) 
scoreboard.grid(row=0,column=0,columnspan=2) 
 
### 
#Code to add stuff to scoreboard ... 
# e.g.  
### 
scorestuff=tk.Label(scoreboard,text="Here is the scoreboard") 
scorestuff.grid(row=0,column=0) 
#End scoreboard 
 
#Start cards. 
cards=tk.Frame(root) 
cards.grid(row=1,column=0) 
### 
# Code to add pitcher and batter cards 
### 
clabel=tk.Label(cards,text="Stuff to add cards here") 
clabel.grid(row=0,column=0) 
#end cards 
 
#Offense/Defense frames.... 
offense=tk.Frame(root) 
offense.grid(row=1,column=1) 
offense.isgridded=True #Dynamically add "isgridded" attribute. 
offense_label=tk.Label(offense,text="Offense is coolest") 
offense_label.grid(row=0,column=0) 
 
defense=tk.Frame(root) 
defense.isgridded=False 
defense_label=tk.Label(defense,text="Defense is coolest") 
defense_label.grid(row=0,column=0) 
 
def switchOffenseDefense(): 
    print "Called" 
    if(offense.isgridded): 
        offense.isgridded=False 
        offense.grid_forget() 
        defense.isgridded=True 
        defense.grid(row=1,column=1) 
     else: 
        defense.isgridded=False 
        defense.grid_forget() 
        offense.isgridded=True 
        offense.grid(row=1,column=1) 
 
 
switch_button=tk.Button(root,text="Switch",command=switchOffenseDefense) 
switch_button.grid(row=2,column=1) 
 
root.mainloop()