开罗语境和持久性? [英] Cairo context and persistence?

查看:96
本文介绍了开罗语境和持久性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am just getting started using pycairo, and I ran into the following interesting error. The program I write creates a simple gtk window, draws a rectangle on it, and then has a callback to draw a random line on any kind of keyboard input. However, it seems that with each keyboard input, I have to create a new context, or I get an error at the moment the program receives first keyboard input (specifically, on the .stroke() line). Error is as follows, if it matters. 'BadDrawable (invalid Pixmap or Window parameter)'. (Details: serial 230 error_code 9 request_code 53 minor_code 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)

感谢您的帮助!

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

(Update: I was playing around, and I realized the following: when I resize the window, all new objects that were added get deleted (or at least don't appear anymore?) )

推荐答案

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

Cairo drawings don't persist at all. (It's best not to think of them as "objects" -- it's not like a canvas library where you can move them around or transform them after you've drawn them.) You have to do all drawing in the expose handler, or it will, as you have found out, disappear whenever the window is redrawn.

由于双重缓冲,cairo上下文不会持续存在:请参见 C文档中的注释,很遗憾,我在PyGTK文档中找不到任何地方.

The cairo context doesn't persist because of double buffering: see the note in the C documentation, which unfortunately I couldn't find anywhere in the PyGTK documentation.

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

In the above code, you should generate the coordinates and color of your random line in the keypress handler and save them in an array. Then in the expose handler, draw each line in the array in order.

这篇关于开罗语境和持久性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆