【问题标题】:Placing child window relative to parent in Tkinter python在Tkinter python中相对于父窗口放置子窗口
【发布时间】:2012-06-24 18:51:54
【问题描述】:

我有一个包含按钮的父小部件。当按下按钮时,我想在与左侧对齐的父小部件正下方打开一个无边框(即没有 Windows 装饰按钮)窗口。我很困惑设置窗口位置的唯一方法(似乎)是使用.geometry(),但更糟糕的是,我似乎无法获得父小部件的绝对坐标 - 我需要.geometry(),仅来自父级父级的偏移量。到目前为止,我的代码是:

# This is the child which appears when the button is pressed.
class ChildPopUpWindow(Frame):
    def __init__(self, parentWgdt):
        win = Toplevel(parentWgdt)
        geom = str(parentWgdt.winfo_x()) + '+' + str(parentWgdt.winfo_y() + parentWgdt.winfo_height())
        win.overrideredirect(1) # No win decoration.
        win.bd = 10
        win.relief = GROOVE
        win.geometry( geom )
        Frame.__init__(self, win)
        # etc. etc.

     # ... and this is the handler for the button being pressed.
     def onDropDown(self):
        popUp = ChildPopUpWindow(self)

这确实会弹出一个窗口,但相对于桌面,而不是父窗口小部件。据我所知,它似乎也没有考虑边界厚度和浮雕。任何人都可以提供一种可以做到这一点的方法吗? .geometry() 是要走的路还是有更好的方法?

【问题讨论】:

  • 你说你想创建一个弹出窗口,你的类名是 PopUpWindow,但你继承自 Frame 而不是 Toplevel。这有什么原因吗?我不太明白你是如何使用它的。是在 ChildPopUpWindow 框架内显示弹出窗口的按钮吗?
  • 对不起,这不是很清楚:onDropDown 是按钮所在框架的处理程序。单击按钮时,想法是在带有按钮的框架下方直接弹出一个无框架(即没有 Windows 最大化/最小化/关闭按钮等)。这将基本上以模态方式起作用,除了弹出窗口上的选择或再次按下按钮会关闭它。通过这种方式,它有点像日历或颜色选择器下拉菜单。
  • @BryanOakley:恐怕顶层/框架的混乱是由于我进行了许多不同的尝试以使其正常工作。我发现的大多数示例似乎都创建了 Toplevel 窗口,然后将其作为参数传递给 Frame-inhereting 类。我想遵循这一点,并尝试在 Frame 之前在其构造函数中使用它们设置 Toplevel 窗口的参数,尽管我想将这些封装在 ChildPopUpWindow 类中。请随时发表评论/纠正。

标签: python window tkinter coordinates


【解决方案1】:

简短的回答是,使用winfo_rootxwinfo_rooty 获取相对于屏幕的坐标。是的,wm_geometry 是精确放置顶层窗口的方法。

例如:

    x = parentWgdt.winfo_rootx()
    y = parentWgdt.winfo_rooty()
    height = parentWgdt.winfo_height()
    geom = "+%d+%d" % (x,y+height)

作为一个友好的建议,我建议不要使用 abbrev var nms。它使代码难以阅读,尤其是当缩写错误时(Wgdt 至少应该是 Wdgt)。 geomgeometry 以及 WgdtWidget 之间的代码大小差异很小,但可读性差异很大。

【讨论】:

  • 感谢您的确认。这看起来基本上就是我所拥有的,所以我猜肯定有其他原因导致它不起作用。同意缩写:我在发布之前匆忙混淆了代码(即客户端IP)。
【解决方案2】:

根据 Tk 手册“https://www.tcl.tk/man/tcl8.4/TkCmd/winfo.htm#M52如果您在创建小部件后立即需要真实宽度,请调用 update 强制几何管理器对其进行排列,或使用 winfo reqwidth 获取窗口的请求宽度而不是实际宽度。

# This code works perfectly
self.update()

self.geometry("+%d+%d" % (self.parent.winfo_rootx()+50,
                          self.parent.winfo_rooty()+50
                         )
             ) 

【讨论】:

    【解决方案3】:

    为了使模态窗口围绕其父窗口居中,我这样做:

        alto_modal = 100
        ancho_modal = 250
        alto_parent = parent.winfo_height()
        ancho_parent = parent.winfo_width()
        x = (ancho_parent - ancho_modal) // 2
        y = (alto_parent - alto_modal) // 2
        self.geometry('{}x{}+{}+{}'.format(ancho_modal, alto_modal, x, y))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      相关资源
      最近更新 更多