使用PySide和PyKDE4移动窗口

5

如何使用窗口管理器移动使用PySide创建的窗口?

我发现kdeui有一个名为NETRootInfo的类,其中包含一个moveResizeRequest方法,正好符合我的要求。以下是示例代码:

from PySide.QtCore import Qt
from PyKDE4 import kdeui
from PySide.QtGui import QX11Info
import sys
from ctypes import CDLL
Xlib = CDLL('libX11.so.6')

def move_window(window, event):
    if event.buttons() & Qt.LeftButton:
        pos = event.buttonDownScreenPos(Qt.LeftButton)
        Xlib.XUngrabPointer(QX11Info.display(), QX11Info.appTime())
        rootinfo = kdeui.NETRootInfo(QX11Info.display(), kdeui.NET.WMMoveResize)
        rootinfo.moveResizeRequest(window.winId(), pos.x(), pos.y(), kdeui.NET.Move)

给我:

TypeError: NETRootInfo(): arguments did not match any overloaded call:
  overload 1: argument 1 has unexpected type 'int'
  overload 2: argument 1 has unexpected type 'int'
  overload 3: argument 1 has unexpected type 'int'
  overload 4: argument 1 has unexpected type 'int'

这个错误是由于QX11Info.display()返回一个长指针,而不是一个Display结构体引起的。
我可以使用PyQt4的QX11Info.display()作为第一个参数传递给NETRootInfo的构造函数,而不是PySide的方式,例如:
...
from PySide.QtGui import QX11Info
from PyQt4.QtGui import QX11Info as QX11InfoQt
...

def move_window(window, event):
    if event.buttons() & Qt.LeftButton:
        pos = event.buttonDownScreenPos(Qt.LeftButton)
        Xlib.XUngrabPointer(QX11Info.display(), QX11Info.appTime())
        rootinfo = kdeui.NETRootInfo(QX11InfoQt.display(), kdeui.NET.WMMoveResize)
        rootinfo.moveResizeRequest(window.winId(), pos.x(), pos.y(), kdeui.NET.Move)

但这样会增加对PyQt4的依赖,除了PySide。

此外,我尝试使用Xlib的XMoveWindow函数,但这会阻止窗口部分地拖动到屏幕外,并且不会提供由Compiz或KWin等窗口管理器提供的移动反馈(例如透明度效果)。

我的问题是:

  1. 如何将PySide的QX11Info.display()转换为可以传递给kdeui.NETRootInfo的“Display”?或者
  2. 如何使用Python和Xlib(使用python-xlib或通过libX11.so)使用类似_NET_WM_MOVERESIZE的消息来移动窗口?

PyQt依赖于Qt——它曾经是GPL,但现在是LGPL;但PyQt仍然是GPL。基本上,一个项目的作者/所有者可以决定使用哪种许可证。PyKDE也在很多年里是GPL(当它由Phil Thompson维护时,后来由Jim Bublitz维护)。但是当KDE接管该项目时,他们决定切换到LGPL(自然而然,因为KDE本身就是LGPL)。 - ekhumoro
为什么在PySide中可以使用QPropertyAnimation,你还想使用kdeui呢?这是PySide实现的链接:http://qt-project.org/forums/viewthread/4927 - Ciasto piekarz
@san 谢谢您的建议,但我不明白 QPropertyAnimation 如何与使用窗口管理器移动窗口有关。 - D K
我是说使用窗口管理器的原因或优势是什么? - Ciasto piekarz
1
这是个好问题。通过使用窗口管理器来移动窗口,你告诉它(毫不意外地)窗口正在移动。这将触发与移动窗口相关的各种插件/效果。例如,在 compiz 和 kwin 中可能启用了一个插件以在拖动窗口时降低窗口的不透明度。此外,可以使用这些 WM 的 Windows 风格对齐功能。如果不使用 WM,则这些功能无法工作,因为 WM 不知道窗口是在移动还是只是重定位(多次)。 - D K
显示剩余4条评论
1个回答

0

我怀疑你最后一次调用实际上具有不同的签名,可能像这样:

moveResizeRequest(<窗口对象>, <整数>, <整数>, <常量>)

而你试图挤压窗口ID(int)。

通过使用pygtk(而不是pykde)并且拥有一些经验,你可能需要枚举给定屏幕中的所有高级窗口以获取窗口句柄对象。

同样,在c++ kde文档中:

display     An X11 Display struct.
supportWindow   The Window id of the supportWindow. The supportWindow must be created by the window manager as a child of the rootWindow. The supportWindow must not be destroyed until the Window Manager exits.

当你试图将某个常量压缩到supportWindow中时。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接