您需要使用双缓冲区技术:
http://en.wikipedia.org/wiki/Multiple_buffering#Double_buffering_in_computer_graphics
那就是您有一个图像,然后绘制该图像:该图像是“后台”缓冲区。您可以使用很多方法来绘制图像。然后,在响应“绘制”信号的回调上,也就是说,实际上在图形存储器中绘制内容的方法只是将您的“幕后”图像丢了。
代码理论( test.py ):
import cairofrom gi.repository import Gtkfrom os.path import abspath, dirname, joinWHERe_AM_I = abspath(dirname(__file__))class MyApp(object): """Double buffer in PyGObject with cairo""" def __init__(self): # Build GUI self.builder = Gtk.Builder() self.glade_file = join(WHERe_AM_I, 'test.glade') self.builder.add_from_file(self.glade_file) # Get objects go = self.builder.get_object self.window = go('window') # Create buffer self.double_buffer = None # Connect signals self.builder.connect_signals(self) # Everything is ready self.window.show() def draw_something(self): """Draw something into the buffer""" db = self.double_buffer if db is not None: # Create cairo context with double buffer as is DESTINATION cc = cairo.Context(db) # Scale to device coordenates cc.scale(db.get_width(), db.get_height()) # Draw a white background cc.set_source_rgb(1, 1, 1) # Draw something, in this case a matrix rows = 10 columns = 10 cell_size = 1.0 / rows line_width = 1.0 line_width, notused = cc.device_to_user(line_width, 0.0) for i in range(rows): for j in range(columns): cc.rectangle(j * cell_size, i * cell_size, cell_size, cell_size) cc.set_line_width(line_width) cc.set_source_rgb(0, 0, 0) cc.stroke() # Flush drawing actions db.flush() else: print('Invalid double buffer') def main_quit(self, widget): """Quit Gtk""" Gtk.main_quit() def on_draw(self, widget, cr): """Throw double buffer into widget drawable""" if self.double_buffer is not None: cr.set_source_surface(self.double_buffer, 0.0, 0.0) cr.paint() else: print('Invalid double buffer') return False def on_configure(self, widget, event, data=None): """Configure the double buffer based on size of the widget""" # Destroy previous buffer if self.double_buffer is not None: self.double_buffer.finish() self.double_buffer = None # Create a new buffer self.double_buffer = cairo.ImageSurface( cairo.FORMAT_ARGB32, widget.get_allocated_width(), widget.get_allocated_height() ) # Initialize the buffer self.draw_something() return Falseif __name__ == '__main__': gui = MyApp() Gtk.main()Glade文件( test.glade ):
<?xml version="1.0" encoding="UTF-8"?><interface> <!-- interface-requires gtk+ 3.0 --> <object id="window"> <property name="can_focus">False</property> <property name="window_position">center-always</property> <property name="default_width">800</property> <property name="default_height">600</property> <signal name="destroy" handler="main_quit" swapped="no"/> <child> <object id="drawingarea1"> <property name="visible">True</property> <property name="can_focus">False</property> <signal name="draw" handler="on_draw" swapped="no"/> <signal name="configure-event" handler="on_configure" swapped="no"/> </object> </child> </object></interface>
依存关系:
Python 2:
sudo apt-get install python-cairo
Python 3:
sudo apt-get install python3-gi-cairo
现在执行:
python test.py
要么
python3 test.py
看起来像什么:
可以在http://cairographics.org/documentation/pycairo/3/reference/index.html中找到有关cairo的所有文档。
亲切的问候



