Переместить окно с помощью PySide и PyKDE4

Как мне переместить окно, созданное с помощью 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.

Я могу использовать QX11Info.display() PyQt4 в качестве первого параметра конструктора 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. Как преобразовать QX11Info.display() PySide в «дисплей», который можно передать в kdeui.NETRootInfo, или
  2. Как мне использовать Python и Xlib (либо с python-xlib, либо через libX11.so), чтобы использовать сообщение типа _NET_WM_MOVERESIZE для перемещения окна?

person D K    schedule 23.09.2012    source источник
comment
Конечно, PyKDE4 уже требует PyQt4, поэтому нет дополнительной зависимости для варианта (1).   -  person ekhumoro    schedule 28.09.2012
comment
Не совсем. PyKDE4 — это оболочка для KDE4. KDE4 требует для работы Qt4, но не Py Qt4. Оболочка Python — это чисто оболочка C++, поэтому она не зависит от PyQt4.   -  person D K    schedule 29.09.2012
comment
Неа. PyKDE теперь поддерживается как часть KDE, но всегда требовал и PyQt, и SIP, и это не изменилось: см. здесь и здесь для получения подробной информации.   -  person ekhumoro    schedule 29.09.2012
comment
Ох. Я этого не понимал. Спасибо вам за ссылки. Просто интересно, как PyKDE4 LGPL, если для этого требуется PyQt4, который является GPL?   -  person D K    schedule 29.09.2012
comment
Что ж, PyQt зависит от Qt, которая была GPL, но теперь является LGPL; и все же PyQt остается GPL. По сути, автор/владелец проекта решает, какое лицензирование использовать. PyKDE также была GPL в течение многих лет (когда она поддерживалась Филом Томпсоном, а затем Джимом Бублицем). Но когда KDE взяла на себя ответственность за проект, они решили перейти на LGPL (вполне естественно, поскольку KDE сама по себе является LGPL).   -  person ekhumoro    schedule 29.09.2012
comment
зачем вам использовать kdeui, когда можно использовать QPropertyAnimationPySide. Вот ссылка на реализацию pyside qt-project.org/forums/viewthread/4927   -  person Ciasto piekarz    schedule 26.12.2013
comment
@san Спасибо за предложение, но я не понимаю, как QPropertyAnimations связаны с перемещением окна с помощью оконного менеджера.   -  person D K    schedule 28.12.2013
comment
Я имел в виду, в чем причина или преимущество использования оконного менеджера?   -  person Ciasto piekarz    schedule 28.12.2013
comment
Это хороший вопрос. Используя оконный менеджер для перемещения окна, вы сообщаете ему (что неудивительно), что окно движется. Это вызовет различные плагины/эффекты, связанные с перемещением окна. Например, в compiz и kwin можно включить плагин для уменьшения непрозрачности окна при его перетаскивании. Кроме того, с этими WM можно использовать привязку в стиле Windows. Без использования WM эти функции не могут работать, потому что WM не знает, перемещается ли окно или просто перемещается (несколько раз).   -  person D K    schedule 28.12.2013


Ответы (1)


Я подозреваю, что ваш последний вызов на самом деле имеет другую подпись, например:

moveResizeRequest(<window object>, <int>, <int>, <const>)

пока вы пытаетесь вместо этого сжать идентификатор окна (int).

имея небольшой опыт работы с pygtk (а не с pykde), вам, вероятно, придется перечислить все окна высокого уровня на данном экране, чтобы получить объект дескриптора окна.

Точно так же из документов С++ 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.

person Dima Tisnek    schedule 30.09.2012