【问题标题】:Using TCL extensions to set native window style in Tkinter使用 TCL 扩展在 Tkinter 中设置原生窗口样式
【发布时间】:2010-07-22 06:09:46
【问题描述】:

pythonware.com/library/tkinter/introduction/... 记录一个 overrideredirect 方法 这将删除标题栏和 边界,如果这还不够,你 必须设置本机窗口样式,我是 不确定 Tkinter 是否给你 一种低级访问,如果没有,请尝试 类似的东西 twapi.magicsplat.com/ui.html#set_window_style TCL 扩展

在之前的一篇文章中,我收到了这个关于如何在 Tkinter 中获得类似于下图的边框的回复。我不熟悉 Tcl 及其扩展。那么如何去做呢?最终目标基本上是在 Tkinter 窗口上获得下面的边框。

编辑:

我在 Windows 7 上使用了以下内容,但似乎并没有改变风格。它可能缺少一些东西。任何帮助将不胜感激,这可能真的很酷!

import string, win32ui, win32con
import Tkinter as tk

root = tk.Tk()

frame = win32ui.CreateWindowFromHandle(string.atoi(root.wm_frame(), 0))
frame.ModifyStyle(win32con.WS_CAPTION, 0, win32con.SWP_FRAMECHANGED)

root.mainloop()

【问题讨论】:

    标签: python tkinter tcl


    【解决方案1】:

    您可以结合使用 Python win32 api 包和 Tkinter。您需要知道的是,Tk 窗口是 Win32 窗口的客户端部分。窗口管理器交互使用包装器处理,该包装器是 Tk 窗口本身的父级。如果你有一个 Tkinter 窗口 'w' 那么你可以为框架创建一个 PyWin32 窗口或者直接操作它。您可以使用 w.wm_frame() 并解析返回的十六进制字符串或通过对 Tk 窗口中的 winfo_id 值使用 GetParent 来获取帧 hwnd(尽管 wm_frame 可能更可靠)。

    import string, win32ui, win32con
    from Tkinter import *
    w = Tk()
    frame = win32ui.CreateWindowFromHandle(string.atoi(w.wm_frame(), 0))
    frame.ModifyStyle(win32con.WS_CAPTION, 0, win32con.SWP_FRAMECHANGED)
    

    这将删除 WS_CAPTION 样式并通知窗口其框架已修改,这会强制重新计算几何,以便将更改传播到 Tk 子窗口。

    编辑—— 以下安排确保我们在窗口完全创建并映射到显示器之后修改窗口样式。

    import string, win32ui, win32con
    from Tkinter import *
    
    def decaption(event):
        w = event.widget
        frame = win32ui.CreateWindowFromHandle(string.atoi(w.wm_frame(), 0))
        frame.ModifyStyle(win32con.WS_CAPTION, 0, win32con.SWP_FRAMECHANGED)
        w.bind("<Map>", None)
    
    root = Tk()
    root.bind("<Map>", decaption)
    root.mainloop()
    

    【讨论】:

    • 它可能只需要重新计算几何图形 - 您是否尝试调整窗口大小并查看标题是否在重绘时突然消失?如果是这样,添加 'w.geometry(w.geometry())' 足以重新断言 Tk 大小和位置并使其重新计算所有内容。
    • 是的,我尝试添加(到上面的代码中)root.geometry(root.geometry())、root.update_idletasks()、和 root.configure(width=225, height=124)。以及手动更改窗户的几何形状(抓住一个角落并移动它)。他们似乎都没有删除标题。是否可以强制窗口在 win32api 方面重绘?也可能导致问题的是我正在调用 root.mainloop() 方法,以便我可以启动 GUI 事件循环。
    • OK - 发生的事情是您在映射窗口之前修改样式,并且它可能在第一次被 Tk 映射时再次被修改。您可以看到这是您使用按钮功能重新安排内容以取消标题的窗口。单击按钮并看到标题消失。在 Tk 中,您可以挂钩 事件以在窗口完全创建并映射到显示器后运行代码。每当映射窗口时都会触发此事件,因此在我们第一次删除回调之后。请参阅编辑以获取示例。
    • 是的,做到了!万分感谢。我一直在尝试这样做一段时间。我相信我也可以使用它来实现其他一些原生 Windows 样式。
    【解决方案2】:

    一种解决方案是绘制自己的边框。使用overrideredirect 移除所有装饰,网格/打包/放置一个填满窗口的画布,然后绘制或使用位图获得您想要的视觉效果。您必须添加自己的绑定来移动和调整窗口大小,但这并不太难。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-11
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 2020-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多