【问题标题】:How do I write text to the root window using Python's Xlib?如何使用 Python 的 Xlib 将文本写入根窗口?
【发布时间】:2019-12-24 19:08:56
【问题描述】:

我正在运行带有dwm 窗口管理器的 Debian 10 稳定 x64 系统,并且我使用的是 Python 3.7.3。从some example codedraw_text method itself 可以看出,我应该能够使用如下代码在根窗口上绘制文本:

#!/usr/bin/env python3

import Xlib
import Xlib.display

display = Xlib.display.Display()
screen = display.screen()
root = screen.root

gc = root.create_gc(foreground = screen.white_pixel, background = screen.black_pixel)
root.draw_text(gc, 1, 1, b"Hello, world!")

此代码运行没有错误,但不显示任何文本。我也尝试过不同的坐标,但没有任何运气。我的根窗口背景只是默认的黑色,所以我不认为文本无法显示,因为我将前景像素颜色设置为白色。

【问题讨论】:

    标签: python xlib


    【解决方案1】:

    您的代码应该在根窗口上绘制文本是对的。你只需要:

    • 确保您的背景确实是根窗口(@98​​7654323@ 很棒)
    • 再次检查坐标: (i) 如果dwm 默认显示顶栏,它可能会隐藏文本。或者只是 [Alt]+b,切换栏 (ii) 如果您有其他窗口,例如您的终端,在顶部,您将看不到文本。
    • 最后执行 XFlush。没有它,请求将保留在客户端中。

    在这里工作的代码(Gentoo amd64/desktop/stable, dwm-6.2, python-3.6.9):

     #!/usr/bin/env python3
    
    import Xlib
    import Xlib.display
    
    display = Xlib.display.Display()
    screen = display.screen()
    root = screen.root
    
    gc = root.create_gc(foreground = screen.white_pixel, background = screen.black_pixel)
    root.draw_text(gc, 100, 100, b"Hello, world!")  # changed the coords more towards the center
    
    display.flush()  # To actually send the request to the server
    

    请注意,如果其他窗口重叠或刷新该位置,文本将会消失。文本会一直保留到,例如,您将一个窗口移到上方(将其删除),或者您更改为另一个具有覆盖这些坐标的窗口的 dwm-Tab。

    如果要防止文字消失,需要循环:

    • 代码上的 while True 循环原样,无论如何都会重绘它
    • 或者,更好的是一个事件循环,它只会在必要时重绘它(见下文)

    暴露事件(参考https://tronche.com/gui/x/xlib/events/exposure/expose.htmlhttp://python-xlib.sourceforge.net/doc/html/python-xlib_13.html#SEC12

    在需要重绘窗口区域时生成

    但是,如果我们监听根窗口的暴露事件,我们没有得到(原因:(参见 dwm 源代码中的 setup 函数)没有根窗口的 ExposureMask)。我的尝试和工作:

    #!/usr/bin/env python3
    
    import Xlib
    from Xlib import display, X   # X is also needed
    
    display = Xlib.display.Display()
    screen = display.screen()
    root = screen.root
    
    #print(root.get_attributes())
    root.change_attributes(event_mask=X.ExposureMask)  # "adds" this event mask
    #print(root.get_attributes())  # see the difference
    
    gc = root.create_gc(foreground = screen.white_pixel, background = screen.black_pixel)
    
    def draw_it():
        root.draw_text(gc, 100, 100, b"Hello, world!")
        display.flush()
    
    draw_it()
    while 1:
        if display.pending_events() != 0:  # check to safely apply next_event
            event = display.next_event()
            if event.type == X.Expose and event.count == 0:
                draw_it()
    

    【讨论】:

    • 这行得通!谢谢你。我错过了冲洗。确保文本“停留”在根窗口上的另一种策略是捕获窗口更改事件,对吗? (我知道这是一个单独的问题)
    • 没错。我根据您的评论编辑了我的答案。 (对我来说,它看起来是同一个问题的一部分)
    • hm,这两个脚本都没有为我做任何事情 - 它静默执行,但屏幕上没有绘制任何文本。
    • 无法真正想象为什么没有更多信息。文本应该出现在根窗口的左上角(也许顶部的其他窗口?)。如果您取消注释第二个脚本中的 2 个打印行,您发现有什么不同吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    相关资源
    最近更新 更多