问题描述
我正在尝试使用Pycairo创建小部件以监视系统,例如Conky。 我正在尝试使用带有Xlib的Cairo Surface直接在X上绘制。
当我尝试实例化cairo.XlibSurface()类时,返回错误:
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实例。那可能是您必须在pygtk旧版代码库中使用C并在Python代码中使用ctypes复制的“缺失链接”。
首先需要进行cairo_xlib_surface_create
调用所需的参数,您可以通过使用Python XLib来获取它们-代码段下方为X Display和Windows Display提供了Window GID和Python包装器,窗口:
from Xlib import X,display
pd = display.Display()
win = pd.screen().root.create_window(0,640,480,pd.screen().root_depth,X.InputOutput,X.CopyFromParent)
win.map()
pd.sync()
xid = xx.__resource__()
,
尚未解决问题:如何在Xlib中使用Pycairo,但是使用Gtk和Pycairo的一种不错的选择。
如何在Xlib中使用Pycairo的谜仍在继续。
将Gtk窗口与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.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,80,80)
cr.fill()
def main():
app = Example()
Gtk.main()
if __name__ == "__main__":
main()
输出: