Python:告诉X为应用保留屏幕空间

6 投票
2 回答
1733 浏览
提问于 2025-04-16 17:21

我正在尝试解决一个问题,就是在使用X窗口管理器的应用程序中预留屏幕空间(也就是在Linux平台上)。我看到过关于这个问题的讨论,尤其是Gtk的解决方案,我也在Qt相关的地方问过同样的问题。不过,针对Qt的问题没有人回应(我在其他论坛也问过),所以我想把我的问题普遍化一下:

有没有一种通用的、适合Python的方式告诉X系统为一个应用程序预留屏幕空间?

谢谢,
本杰明

2 个回答

0

嗯,我不太确定你能不能这样做。你的操作系统会为用户程序在内存中保留一个区域。一个程序可以通过malloc()来申请内存空间,但这块空间是操作系统为当前程序预留的。你是想把这个程序分叉成一个子进程吗?还是想执行一个新的实例?

6

经过一些研究,我找到了使用 Python-Xlib 的解决方案。

在生成窗口的代码中,可以获取窗口的 ID,这个 ID 是在 X 系统中识别窗口的标识。根据你使用的图形界面工具包,获取这个 ID 的方法可能会有所不同。比如,Qt4 提供了 QWidget.winId(),而 Gtk+2 则有自己的一套方法来为窗口预留空间,我还没有尝试过 Gtk+3,但听说应该有一个 window_id 属性。

因为在窗口显示后才能调用 X 来预留空间,所以在大多数情况下,需要在进入主事件循环后再进行查询。

下面的例子展示了一个使用 PyQt4 的 Qt4 的案例。为了在窗口显示后获取它,我们在 QApplication 进入主循环之前启动一个线程,这个线程会不断查询 X,直到成功“抓住”窗口。在这个例子中,空间被预留在屏幕的顶部,预留的高度与我们为其预留空间的 QWidget 的高度相等。

def fix_window(self):
        set = False
        while set == False:
            try:
                window = myXwindow.Window(self.parent().winId())
                if window != None:
                    height = self.parent().height()
                    window.reserve_space(0, 0, height, 0)
                    set = True
                else:
                    self.sleep(1)
            except:
                raise

在上面的例子中,myXwindow 是一个使用 Python-Xlib 的自定义模块。以下是这个模块的内容,其中 Xlib 查询 X 的 Display(),然后创建一个窗口对象,这个对象是一个抽象模型,用来引用我们在 X 中显示的窗口。在更改这个模型的属性后,我们可以通过 Display().sync() 来应用这些更改。预留空间的方法是 change_property(),其中会根据 Freedesktop.org 标准 传递一系列参数。

class Window(object):
   
    def __init__(self, windowID):

        self._display = Display()
        self._window = self._display.create_resource_object('window', windowID)
    
    def reserve_space(self, left=0, right=0, top=0, bottom=0):

        LEFT    = left
        RIGHT   = right
        TOP     = top
        BOTTOM  = bottom

        self._window.change_property(self._display.intern_atom('_NET_WM_STRUT'),
                                    self._display.intern_atom('CARDINAL'),
                                    32, [LEFT, RIGHT, TOP, BOTTOM])
        self._display.sync()

注意:为了更改窗口属性,必须保持创建窗口对象的 Display() 实例,因此它被存储在一个变量中。

撰写回答