您需要使用双缓冲区技术:
http://en.wikipedia.org/wiki/Multiple_buffering#Double_buffering_in_computer_graphics
那就是您有一个图像,然后绘制该图像:该图像是“后台”缓冲区。您可以使用很多方法来绘制图像。然后,在响应“绘制”信号的回调上,也就是说,实际上在图形存储器中绘制内容的方法只是将您的“幕后”图像丢了。
代码理论( ):
import cairo
from gi.repository import Gtk
from os.path import abspath, dirname, join
WHERE_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 False
if __name__ == '__main__':
gui = MyApp()
Gtk.main()
Glade文件( ):
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkWindow" 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 class="GtkDrawingArea" 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的所有文档。
亲切的问候