我正在開發一個用開羅+ Gtk編寫的應用程序。 請注意,由於retrocompatibility問題,我被迫使用Python作爲編程語言,PyGTK作爲包裝,以及GTK庫,v.2.24。 沒有機會使用C/C++和/或GTK3!開羅+橡皮筋選擇:gui非常非常慢
我的應用程序需要(重新)繪製的數據在屏幕上大量暴露方法(顯然)的每次調用。
我只是給用戶一個機會手動選擇以前用開羅繪製的一些對象。 因爲我在繪製gtk.DrawingAreas,所以我似乎必須手動實現橡皮筋選擇功能。
這是一個問題:
有什麼辦法重繪每鼠標移動橡皮筋矩形,避免重繪所有其他屏幕上的對象?
我會重繪只有出於性能原因的選擇矩形。
由於大量的圖形對象,我的GUI非常慢。不幸的是,儘管多次嘗試,我別無選擇:重繪全部或重繪任何東西!
第一件事就在我腦海裏:有沒有什麼辦法在DrawingArea與大部分數據和鼠標光標之間覆蓋中間級別?通過調用queue_draw_area()函數調用 沒有性能收益。
一個簡單的自包含代碼示例如下:顯然,在這種情況下,使用cairo繪製極其簡單的圖形對象。
import gtk
from gtk import gdk
class Canvas(gtk.DrawingArea):
# the list of points is passed as argument
def __init__(self, points):
super(Canvas, self).__init__()
self.points = points
self.set_size_request(400, 400)
# Coordinates of the left-top angle of the selection rect
self.startPoint = None
self.endPoint = None
# Pixmap to drawing rubber band selection
self.pixmap = None
self.connect("expose_event", self.expose_handler)
self.connect("motion_notify_event", self.mouseMove_handler)
self.set_events(gtk.gdk.EXPOSURE_MASK
| gtk.gdk.LEAVE_NOTIFY_MASK
| gtk.gdk.BUTTON_PRESS_MASK
| gtk.gdk.POINTER_MOTION_MASK
| gtk.gdk.POINTER_MOTION_HINT_MASK)
# Method to paint lines and/or rubberband on screen
def expose_handler(self, widget, event):
rect = widget.get_allocation()
w = rect.width
h = rect.height
ctx = widget.window.cairo_create()
ctx.set_line_width(7)
ctx.set_source_rgb(255, 0, 0)
ctx.save()
for i in range(0, len(self.points)):
currPoint = self.points[i]
currX = float(currPoint[0])
currY = float(currPoint[1])
nextIndex = i + 1
if (nextIndex == len(self.points)):
continue
nextPoint = self.points[nextIndex]
nextX = float(nextPoint[0])
nextY = float(nextPoint[1])
ctx.move_to(currX, currY)
ctx.line_to(nextX, nextY)
ctx.restore()
ctx.close_path()
ctx.stroke()
# rubber band
if self.pixmap != None:
width = self.endPoint[0] - self.startPoint[0]
height = self.endPoint[1] - self.startPoint[1]
if width < 0 or height < 0:
tempEndPoint = self.endPoint
self.endPoint = self.startPoint
self.startPoint = tempEndPoint
height = self.endPoint[1] - self.startPoint[1]
width = self.endPoint[0] - self.startPoint[0]
widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.startPoint[0], self.startPoint[1], self.startPoint[0], self.startPoint[1], abs(width), abs(height))
def mouseMove_handler(self, widget, event):
x, y, state = event.window.get_pointer()
if (state & gtk.gdk.BUTTON1_MASK):
if (state & gtk.gdk.CONTROL_MASK):
if self.startPoint == None:
self.startPoint = (x,y)
self.endPoint = (x,y)
else:
self.endPoint = (x,y)
tempPixmap = gtk.gdk.Pixmap(widget.window, 400, 400)
height = self.endPoint[1] - self.startPoint[1]
width = self.endPoint[0] - self.startPoint[0]
gc = self.window.new_gc()
gc.set_foreground(self.get_colormap().alloc_color("#FF8000"))
gc.fill = gtk.gdk.STIPPLED
tempPixmap.draw_rectangle(gc, True, self.startPoint[0], self.startPoint[1], abs(width), abs(height))
self.pixmap = tempPixmap
# widget.queue_draw_area()
widget.queue_draw()
else:
if (self.pixmap != None):
self.pixmap = None
# ...do something...
# widget.queue_draw_area(self.startPoint[0], self.startPoint[1],)
widget.queue_draw()
li1 = [(20,20), (380,20), (380,380), (20,380)]
window = gtk.Window()
canvas = Canvas(li1)
window.add(canvas)
window.connect("destroy", lambda w: gtk.main_quit())
window.show_all()
gtk.main()
謝謝!
IT
用GTK + /開羅繪圖時
您好!請檢查我的[關於在GTK中繪圖的問題](http://stackoverflow.com/questions/26497939/gtk-theme-in-gtk-windows)。 –