其他分享
首页 > 其他分享> > 开罗上下文和持久性?

开罗上下文和持久性?

作者:互联网

我刚刚开始使用pycairo,但遇到了以下有趣的错误.我编写的程序将创建一个简单的gtk窗口,在其上绘制一个矩形,然后具有一个回调以在任何类型的键盘输入上绘制随机线.但是,似乎每个键盘输入都必须创建一个新的上下文,否则在程序接收到第一个键盘输入(特别是在.stroke()行上)时会出现错误.如果重要,则错误如下. ‘BadDrawable(无效的Pixmap或Window参数)’. (详细信息:串行230错误代码9请求代码53次要代码0)

#! /usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk, gobject, cairo, math, random
# Create a GTK+ widget on which we will draw using Cairo
class Screen(gtk.DrawingArea):
# Draw in response to an expose-event
  __gsignals__ = { "expose-event": "override" }

  # Handle the expose-event by drawing
  def do_expose_event(self, event):
    # Create the cairo context
    self.cr = self.window.cairo_create()
    # Restrict Cairo to the exposed area; avoid extra work
    self.cr.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
    self.cr.clip()

    self.draw(*self.window.get_size())

  def key_press_event(self, *args):
    # print args
    self.cr = self.window.cairo_create() # This is the line I have to add
    # in order to make this function not throw the error. Note that cr is only
    # given as attribute of self in order to stop it going out of scope when this line
    # doesn't exist
    self.cr.set_source_rgb(random.random(), random.random(), random.random())
    self.cr.move_to(*[z/2.0 for z in self.window.get_size()])
    self.cr.line_to(*[z*random.random() for z in self.window.get_size()])
    self.cr.stroke()

  def draw(self, width, height):
    # Fill the background with gray
    self.cr.set_source_rgb(.5,.5,.5)
    self.cr.rectangle(0, 0, width,height)
    self.cr.fill()

    self.cr.set_source_rgb(1,0,0)
    self.cr.arc(width/2.0, height/2.0, min(width,height)/2.0 - 20.0, 0.0, 2.0*math.pi)
    self.cr.stroke()

#create a gtk window, attach to exit button, and whatever is passed as arg becomes the body of the window. AWESOME
def run(Widget):
  window = gtk.Window()
  widget = Widget()
  window.connect("delete-event", gtk.main_quit)
  window.connect('key-press-event',widget.key_press_event)
  widget.show()
  window.add(widget)
  window.present()
  gtk.main()

if __name__ == "__main__":
  run(Screen)

谢谢你的帮助!

(更新:我在玩耍,并且意识到了以下几点:调整窗口大小时,所有添加的新对象都会被删除(或者至少不再显示?))

解决方法:

开罗的图纸根本没有保留. (最好不要将它们视为“对象”,它不像一个画布库,在绘制它们之后,您可以在其中移动它们或对其进行变换.)您必须在暴露处理程序中进行所有绘制,否则如您所知,只要重新绘制窗口,它就会消失.

由于双重缓冲,cairo上下文无法持久:参见note in the C documentation,不幸的是,我在PyGTK文档中找不到任何内容.

在上面的代码中,您应该在按键处理程序中生成随机线的坐标和颜色,并将其保存在数组中.然后在暴露处理程序中,按顺序绘制数组中的每一行.

标签:cairo,gtk,pygtk,pycairo,python
来源: https://codeday.me/bug/20191209/2097156.html