Pycairo:如何正确实例化 cairo.XlibSurface()?
Pycairo: How to correctly instance cairo.XlibSurface()?
我正在尝试使用 Pycairo 创建小部件来监控系统,例如 Conky。
我正在尝试直接在 X 上绘图,使用带有 Xlib 的 Cairo Surface。
当我尝试实例化 cairo.XlibSurface() class 时,返回错误:
TypeError: The XlibSurface type cannot be directly instantiated
我的简单代码:
import cairo
surface = cairo.XlibSurface()
如何正确实例化 cairo.XlibSurface() ?
提前致谢
[不完整的答案]
我有足够的片段,这可能作为答案比作为评论更有用。很抱歉没能追根究底。
documentation for PyCairo XlibSurface 本身只提到它可以通过对 GTK 的某些调用来实例化 - 我不确定这是否只是对 GTK2 的旧绑定。我可以找到一个片段来使用 GTK +3 为我获取 Cairo 上下文,但如果不求助于 ctypes,从 Cairo 上下文返回到它使用的 Surface 似乎是不可行的。
因此,您基本上需要使用 Python ctypes 调用 Cairo's C cairo_xlib_surface_create
,并找到一种使用 ctypes 从指针创建 Python cairo.XlibSurface 实例的方法由上面的函数返回。那就是您可能必须在 C 中的 pygtk 遗留代码库中找到的“缺失 link”,并在 Python 代码中使用 ctypes 进行复制。
至于首先调用 cairo_xlib_surface_create
所需的参数,您可能可以使用 Python XLib 获取它们 - 下面的代码片段为您提供了 Window GID 和 Python X 显示器和 Window:
的包装器
from Xlib import X, display
pd = display.Display()
win = pd.screen().root.create_window(0, 0, 640, 480, 0, pd.screen().root_depth, X.InputOutput, X.CopyFromParent)
win.map()
pd.sync()
xid = xx.__resource__()
没有解决问题:How to use Pycairo with Xlib,但是使用 Gtk 和 Pycairo 的优雅替代方案。
如何将 Pycairo 与 Xlib 一起使用的谜团仍在继续。
将 Gtk window 与 Gdk.WindowTypeHint.DESKTOP
结合使用,获得优雅的输出。
import gi
gi.require_versions({
'Gdk': '3.0',
'Gtk': '3.0',
'Wnck': '3.0',
'Gst': '1.0',
'AppIndicator3': '0.1',
})
from gi.repository import Gtk, Gdk
import cairo
class Example(Gtk.Window):
def __init__(self):
super(Example, self).__init__()
self.tran_setup()
self.init_ui()
def init_ui(self):
self.connect("draw", self.on_draw)
# self.set_title("Transparent window")
self.resize(300, 250)
self.set_position(Gtk.WindowPosition.NONE)
self.move(0, 40)
self.connect("delete-event", Gtk.main_quit)
# The magic is here
self.set_type_hint(Gdk.WindowTypeHint.DESKTOP)
self.show_all()
def tran_setup(self):
self.set_app_paintable(True)
screen = self.get_screen()
#print(self.get_type_hint())
visual = screen.get_rgba_visual()
if visual != None and screen.is_composited():
self.set_visual(visual)
def on_draw(self, wid, cr):
cr.set_source_rgba(0.2, 0.2, 0.2, 0.4)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.paint()
cr.set_source_rgb(0.6, 0.6, 0.6)
cr.rectangle(20, 20, 120, 80)
cr.fill()
self.draw(cr)
def draw(self, cr):
cr.set_source_rgb(0, 256, 256)
cr.rectangle(180, 20, 80, 80)
cr.fill()
def main():
app = Example()
Gtk.main()
if __name__ == "__main__":
main()
输出:
我正在尝试使用 Pycairo 创建小部件来监控系统,例如 Conky。 我正在尝试直接在 X 上绘图,使用带有 Xlib 的 Cairo Surface。
当我尝试实例化 cairo.XlibSurface() class 时,返回错误:
TypeError: The XlibSurface type cannot be directly instantiated
我的简单代码:
import cairo
surface = cairo.XlibSurface()
如何正确实例化 cairo.XlibSurface() ?
提前致谢
[不完整的答案] 我有足够的片段,这可能作为答案比作为评论更有用。很抱歉没能追根究底。
documentation for PyCairo XlibSurface 本身只提到它可以通过对 GTK 的某些调用来实例化 - 我不确定这是否只是对 GTK2 的旧绑定。我可以找到一个片段来使用 GTK +3 为我获取 Cairo 上下文,但如果不求助于 ctypes,从 Cairo 上下文返回到它使用的 Surface 似乎是不可行的。
因此,您基本上需要使用 Python ctypes 调用 Cairo's C cairo_xlib_surface_create
,并找到一种使用 ctypes 从指针创建 Python cairo.XlibSurface 实例的方法由上面的函数返回。那就是您可能必须在 C 中的 pygtk 遗留代码库中找到的“缺失 link”,并在 Python 代码中使用 ctypes 进行复制。
至于首先调用 cairo_xlib_surface_create
所需的参数,您可能可以使用 Python XLib 获取它们 - 下面的代码片段为您提供了 Window GID 和 Python X 显示器和 Window:
from Xlib import X, display
pd = display.Display()
win = pd.screen().root.create_window(0, 0, 640, 480, 0, pd.screen().root_depth, X.InputOutput, X.CopyFromParent)
win.map()
pd.sync()
xid = xx.__resource__()
没有解决问题:How to use Pycairo with Xlib,但是使用 Gtk 和 Pycairo 的优雅替代方案。
如何将 Pycairo 与 Xlib 一起使用的谜团仍在继续。
将 Gtk window 与 Gdk.WindowTypeHint.DESKTOP
结合使用,获得优雅的输出。
import gi
gi.require_versions({
'Gdk': '3.0',
'Gtk': '3.0',
'Wnck': '3.0',
'Gst': '1.0',
'AppIndicator3': '0.1',
})
from gi.repository import Gtk, Gdk
import cairo
class Example(Gtk.Window):
def __init__(self):
super(Example, self).__init__()
self.tran_setup()
self.init_ui()
def init_ui(self):
self.connect("draw", self.on_draw)
# self.set_title("Transparent window")
self.resize(300, 250)
self.set_position(Gtk.WindowPosition.NONE)
self.move(0, 40)
self.connect("delete-event", Gtk.main_quit)
# The magic is here
self.set_type_hint(Gdk.WindowTypeHint.DESKTOP)
self.show_all()
def tran_setup(self):
self.set_app_paintable(True)
screen = self.get_screen()
#print(self.get_type_hint())
visual = screen.get_rgba_visual()
if visual != None and screen.is_composited():
self.set_visual(visual)
def on_draw(self, wid, cr):
cr.set_source_rgba(0.2, 0.2, 0.2, 0.4)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.paint()
cr.set_source_rgb(0.6, 0.6, 0.6)
cr.rectangle(20, 20, 120, 80)
cr.fill()
self.draw(cr)
def draw(self, cr):
cr.set_source_rgb(0, 256, 256)
cr.rectangle(180, 20, 80, 80)
cr.fill()
def main():
app = Example()
Gtk.main()
if __name__ == "__main__":
main()
输出: