我需要繪製成千上萬,未來可能成千上萬個簡單的2D對象(圓形,矩形,一些填充,標記...)到一個小部件。如何快速繪製10000+ 2D圖形對象?
在同一個程序中,我需要GUI小部件(按鈕,文本輸入,複選框)。
我用C++和Python試用了Gtk,Qt和SDL。第一個結果是預料之中的:C++和Python顯示相同的性能,因爲它們在後端調用相同的C或C++例程。
第二個結果是沒有一個庫有很大的不同。數字:22500矩形(150 * 150)需要大約一秒鐘來更新。由於(a)新的數據,即更多的矩形,和(b)用戶交互,即縮放,平移等等,將會不斷地向上調整,第二種方法需要很長的時間!
什麼是更快的方法。小例子非常感謝。 Python和C++很好。其他庫應該很容易在Linux上訪問和安裝。
也許我只是做錯了。
ps。我不張貼我的測試代碼,因爲我不想偏見答案。我不希望被糾正了我的代碼,我想這樣做的最快方法...
編輯:
好吧,我會增加我的GTK測試:
#!/bin/env python2
import gtk
import gobject
import gtk.gdk
class GraphWidget(gtk.DrawingArea):
__gsignals__ = {
'expose-event': 'override',
'clicked' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, gtk.gdk.Event))
}
def __init__(self,window):
gtk.DrawingArea.__init__(self)
#self.win = window
self.zoom_ratio = 1.0
self.dx = 40
self.dy = 40
def do_expose_event(self, event):
cr = self.window.cairo_create()
cr.set_source_rgba(1.0, 0.9, 0.8, 1.0)
cr.paint()
cr.translate(self.dx, self.dy)
cr.scale(self.zoom_ratio,self.zoom_ratio)
self.draw(cr)
def draw(self, cr):
n = 150
cr.set_source_rgba(0.,1.,1.,1.0)
for i in range(n):
for j in range(n):
cr.arc(i*30, j*30, 10, 0, 6.2832)
cr.close_path()
cr.fill()
cr.set_source_rgba(0.,0.,1.,1.0)
for i in range(n):
for j in range(n):
cr.arc(i*30, j*30, 10, 0, 6.2832)
cr.move_to(i*30-10, j*30)
cr.show_text("hu")
cr.stroke()
def on_zoom(self, zoom_factor):
self.zoom_ratio *= zoom_factor
self.queue_draw()
def on_translate(self,dx,dy):
self.dx += dx
self.dy += dy
self.queue_draw()
class TestWindow(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.widget = GraphWidget(self)
self.add(self.widget)
self.show_all()
# connect key press events
self.connect('key-press-event', self.on_key_press_event)
self.connect('destroy', gtk.main_quit)
self.widget.queue_draw()
def on_key_press_event(self, widget, event):
if event.keyval == gtk.keysyms.space and not (event.state & gtk.gdk.CONTROL_MASK):
self.on_run(widget)
return True
elif event.keyval == gtk.keysyms.r:
self.on_refresh(widget)
return True
elif event.keyval == gtk.keysyms.Left:
self.widget.on_translate(-100, 0)
elif event.keyval == gtk.keysyms.Right:
self.widget.on_translate(100, 0)
elif event.keyval == gtk.keysyms.Up:
self.widget.on_translate(0, -100)
elif event.keyval == gtk.keysyms.Down:
self.widget.on_translate(0, 100)
elif event.keyval == gtk.keysyms.Page_Down:
self.widget.on_zoom(0.7)
elif event.keyval == gtk.keysyms.Page_Up:
self.widget.on_zoom(1.3)
if __name__ == '__main__':
win = TestWindow()
gtk.main()
而SDL實驗:
#!/usr/bin/env python
import sdl2
import sdl2.ext as sdl2ext
dx = 0
dy = 0
zoom_factor = 1.
n_objects = 150
sdl2ext.init()
window = sdl2ext.Window('hallo',
size=(800, 600),
flags= sdl2.SDL_WINDOW_RESIZABLE)
window.show()
renderer = sdl2ext.RenderContext(window)
renderer.color = sdl2ext.Color(255,155,25)
def draw():
renderer.clear()
for i in xrange(n_objects):
for j in xrange(n_objects):
renderer.fill([int((i*30+dx)*zoom_factor),
int((j*30+dy)*zoom_factor),
int(20*zoom_factor),
int(20*zoom_factor)],
sdl2ext.Color(255,25,55))
renderer.draw_rect([int((i*30+dx)*zoom_factor),
int((j*30+dy)*zoom_factor),
int(20*zoom_factor),
int(20*zoom_factor)],
sdl2ext.Color(255,255,255))
renderer.present()
draw()
running = True
while running:
for e in sdl2ext.get_events():
if e.type == sdl2.SDL_QUIT:
running = False
break
if e.type == sdl2.SDL_KEYDOWN:
if e.key.keysym.sym == sdl2.SDLK_ESCAPE:
running = False
break
elif e.key.keysym.sym == sdl2.SDLK_RIGHT:
dx += 50
draw()
elif e.key.keysym.sym == sdl2.SDLK_LEFT:
dx -= 50
draw()
elif e.key.keysym.sym == sdl2.SDLK_UP:
dy += 50
draw()
elif e.key.keysym.sym == sdl2.SDLK_DOWN:
dy -= 50
draw()
elif e.key.keysym.sym == sdl2.SDLK_PAGEUP:
zoom_factor *= 1.2
draw()
elif e.key.keysym.sym == sdl2.SDLK_PAGEDOWN:
zoom_factor /= 1.2
draw()
Qt的試驗是由我的同事這樣做,我沒有代碼現在...
所以,你要我們從地上爬起來爲你的代碼呢?如果您包含一些代碼,您獲得答案的可能性將大大增加。 – IanAuld
你認爲OpenGL? –
@IanAuld:好的... – steffen