前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Tkinter:为什么多个Frame相互覆盖?

Tkinter:为什么多个Frame相互覆盖?

原创
作者头像
华科云商小徐
发布2024-10-12 15:49:50
发布2024-10-12 15:49:50
10600
代码可运行
举报
文章被收录于专栏:小徐学爬虫小徐学爬虫
运行总次数:0
代码可运行

Tkinter 中,Frame 是一个容器部件,用于组织和管理布局。如果多个 Frame 出现在同一个父容器中并且看起来相互覆盖,通常与布局管理器的使用方式或控件的创建顺序有关。

以下是几个常见的原因和解决方案,帮助你了解为什么多个 Frame 会相互覆盖:

问题背景

我在使用 Tkinter 构建 Python GUI 时遇到一个问题。我的想法是在根 Frame 中构建多个 Frame。我可以让 2 个 Frame 显示出来,但第 3 个 Frame 会覆盖第 2 个 Frame。我尝试将 pack() 和 grid() 都用作根 Frame 中的布局管理器。

我希望有一个“Stuff At The Top”Frame 和一个“Stuff At The Bottom”Frame,中间有 1 个 Cat1 Frame 和 1 到 8 个 Cat2 Frames。该 GUI 需要能够随着应用程序发现它控制的 Cat2 控件的数量而动态地重新构建。

我还遇到另一个小问题。自从我引入了 Cat2Frame 类并将 tkFont 变量移至全局作用域后,我的 12 号字体仍然只有 9 号。

下面是我经过清理的代码片段。(尚未涉及底部 Frame。)

代码语言:javascript
代码运行次数:0
运行
复制
def anchor(widget, rows=0, cols=0):
    """Takes care of anchoring/stretching widgets via grid 'sticky'"""
    for r in range(rows):
        widget.rowconfigure(r, weight=1)
    for c in range(cols):
        widget.columnconfigure(c, weight=1)
​
​
font_ = None
bold_ = None
bold_12 = None
​
class TkinterGui():
    """Tkinter implementation of the GUI"""
    def __init__(self):
        """Create the Tkinter GUI"""
        self._top_level = None
        self._top_row   = None
        self._buildGui(_TITLE)
​
​
    def _buildGui(self, title):
        """Build the Tkinter GUI"""
        self._top_level  = Tkinter.Tk()
        font_ = tkFont.Font(family='FreeSans', size=9)
        bold_ = tkFont.Font(family='FreeSans', size=9, weight='bold')
        bold_12 = tkFont.Font(family='FreeSans', size=12, weight='bold')
        anchor(self._top_level, 4, 1)
        self._top_row = 0
        self._buildTop()
        self._top_row = 1
        self._buildCat1()
        t1 = Cat2Frame(self._top_level, "Cat2 1")
        self._top_row = 2
        t1.place_frame(self._top_row)
        t5 = Cat2Frame(self._top_level, "Cat2 5")
        self._top_row = 3
        t5.place_frame(self._top_row)
        self._top_level.title(title)
​
​
    def _buildTop(self):
        """Private method to build the Top frame of the GUI."""
        top_frame = Tkinter.Frame(self._top_level, name='top_frame')
        anchor(top_frame, 1, 3)
        top_frame.columnconfigure(0, weight=2)
        top_frame.columnconfigure(1, weight=5)
        col1_label = Tkinter.Label(top_frame
                                   , name='col1_label'
                                   , text="Col1"
                                   , font=bold_12
                                   , width=20
                                    ).grid(row=0
                                         , column=0
                                         , sticky=N+E+W+S
                                          )
        col2_label = Tkinter.Label(top_frame
                                   , name='col2_label'
                                   , text="Col2"
                                   , font=bold_12
                                   , width=40
                                    ).grid(row=0
                                         , column=1
                                         , sticky=N+E+W+S
                                          )
        top_button = Tkinter.Button(top_frame
                                    , name='top_button'
                                    , text='Top Button'
                                    , font=bold_
                                     ).grid(row=0
                                          , column=2
                                          , sticky=E
                                           )
        top_frame.grid(row=self._top_row, column=0, sticky=N+W)
​
​
    def _buildCat1(self):
        """Private method to build the Cat1 frame of the GUI"""
        cat1_frame = Tkinter.Frame(self._top_level, name='cat1_frame')
        anchor(cat1_frame, 3, 3)
        cur_row = 0
        cat1_frame.columnconfigure(2, weight=6)
        Tkinter.Label(cat1_frame
                    , name='cat1_label'
                    , text='Cat1'
                    , font=bold_
                     ).grid(row=cur_row, column=0, sticky=N+E+W+S)
        cat1_size = Tkinter.Text(cat1_frame
                                 , name='cat1_size'
                                 , state=DISABLED
                                 , font=font_
                                 , height=1
                                 , width=10
                                  ).grid(row=cur_row
                                       , column=1
                                       , sticky=E
                                        )
        cat1_status = Tkinter.Text(cat1_frame
                                   , name='cat1_status'
                                   , state=DISABLED
                                   , font=font_
                                   , height=3
                                   , width=72
                                    ).grid(row=cur_row
                                         , column=2
                                         , rowspan=3
                                         , sticky=N+E+W+S
                                          )
        cur_row += 1
        cat1_model = Tkinter.Text(cat1_frame
                                  , name='cat1_model'
                                  , state=DISABLED
                                  , font=font_
                                  , height=1
                                  , width=30
                                   ).grid(row=cur_row
                                        , column=0
                                        , columnspan=2
                                        , sticky=N+W
                                         )
        cur_row += 1
        cat1_serial = Tkinter.Text(cat1_frame
                                   , name='cat1_serial'
                                   , state=DISABLED
                                   , font=font_
                                   , height=1
                                   , width=30
                                    ).grid(row=cur_row
                                         , column=0
                                         , columnspan=2
                                         , sticky=N+W
                                          )
        cat1_frame.grid(row=self._top_row, column=0, sticky=N+W)
​
​
class Cat2Frame():
    """Class encapsulation for a Cat2 Frame in the GUI"""
    def __init__(self, parent, t_label):
        """Initialize a Cat2 Frame in the GUI"""
        self._frame = Tkinter.Frame(parent, name='cat2_frame')
        anchor(self._frame, 3, 4)
        self.cur_row = 0
        self._frame.columnconfigure(2, weight=5)
​
        self._label = Tkinter.Label(self._frame
                                  , name='cat2_label'
                                  , text=t_label
                                  , font=bold_
                                   )
        self._size = Tkinter.Text(self._frame
                                , name='cat2_size'
                                , state=DISABLED
                                , font=font_
                                , height=1
                                , width=10
                                 )
        self._status = Tkinter.Text(self._frame
                                  , name='cat2_status'
                                  , state=DISABLED
                                  , font=font_
                                  , height=3
                                  , width=60
                                   )
        self._control = Tkinter.IntVar()
        self._enabled = Tkinter.Radiobutton(self._frame
                                          , name='cat2_enabled'
                                          , variable=self._control
                                          , text='Enabled'
                                          , font=bold_
                                          , value=1
                                           )
        self._model = Tkinter.Text(self._frame
                                 , name='cat2_model'
                                 , state=DISABLED
                                 , font=font_
                                 , height=1
                                 , width=30
                                  )
        self._disabled = Tkinter.Radiobutton(self._frame
                                           , name='cat2_disabled'
                                           , variable=self._control
                                           , text='Disabled'
                                           , font=bold_
                                           , value=0
                                            )
        self._serial = Tkinter.Text(self._frame
                                  , name='cat2_serial'
                                  , state=DISABLED
                                  , font=font_
                                  , height=1
                                  , width=3

当多个 FrameTkinter 中相互覆盖时,问题通常与布局管理器的使用有关。要避免这种情况,可以:

  1. 确保使用布局管理器时,明确指定位置 (pack(side=...)grid(row=..., column=...))。
  2. 不要在同一个容器中混用 pack()grid()
  3. 使用 place() 布局时,注意坐标设置,确保不同部件不在同一位置。
  4. 如果 Frame 没有子部件,确保为它们设置合适的宽度和高度。

通过合理的布局管理,可以确保 Frame 之间不会发生相互覆盖的问题。如果有具体的代码,我可以帮助进一步调试。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档