RkBlog

Hardware, programming and astronomy tutorials and reviews.

QGraphicsView i QGraphicsScene

Opis widżetów do wizualizacji złożonych obiektów 2D (np. grafik) w PyQt

QGraphicsView to klasa dostarczająca widżet wizualizujący obiekty QGraphicsScene - powierzchni zawierających dużą ilość graficznych elementów 2D. Scena (QGraphicsScene) może zawierać różne elementy (dodawane za pomocą addEllipse(), addLine(), addPath(), addPixmap(), addPolygon(), addRect() lub addText()) i wyświetlać je w zadany sposób. Oto przykład wyświetlenia pliku graficznego:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

app = QApplication(sys.argv)

grview = QGraphicsView()
scene = QGraphicsScene()
scene.addPixmap(QPixmap('pic.jpg'))
grview.setScene(scene)

grview.show()

sys.exit(app.exec_())
Sceny mogą być renderowane także za pomocą OpenGL, co przydaje się w przypadku złożonych elementów, lub wykonywania na nich różnych operacji (będą one przeprowadzane w GPU karty graficznej, a nie w mało wydajnym dla tego typu operacji CPU). Obsługa renderowania scen za pomocą OpenGL sprowadza się do dodania jednej linii kodu:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtOpenGL import *

app = QApplication(sys.argv)

grview = QGraphicsView()
grview.setViewport(QGLWidget())
scene = QGraphicsScene()
scene.addPixmap(QPixmap('pic.jpg'))
grview.setScene(scene)

grview.show()

sys.exit(app.exec_())
Efekt w obu przypadkach będzie ten sam:
qgraphicsview
QGraphicsView i QGraphicsScene oferują bardzo wiele. Przykładowo jeżeli chcemy skalować wyświetlany obrazek do bieżącego rozmiaru okna wystarczy skorzystać ze zdarzeń:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class ImageView(QGraphicsView):
	def __init__(self, parent=None, origPixmap=None):
		"""
		QGraphicsView that will show an image scaled to the current widget size
		using events
		"""
		super(ImageView, self).__init__(parent)
		self.origPixmap = origPixmap
		QMetaObject.connectSlotsByName(self)
	
	def resizeEvent(self, event):
		"""
		Handle the resize event.
		"""
		size = event.size()
		item =  self.items()[0]
		
		# using current pixmap after n-resizes would get really blurry image
		#pixmap = item.pixmap()
		pixmap = self.origPixmap
		
		pixmap = pixmap.scaled(size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
		self.centerOn(1.0, 1.0)
		item.setPixmap(pixmap)


app = QApplication(sys.argv)

pic = QPixmap('pic.jpg')
grview = ImageView(origPixmap=pic)

scene = QGraphicsScene()
scene.addPixmap(pic)

grview.setScene(scene)
grview.show()

sys.exit(app.exec_())
Stworzyliśmy własną klasę dziedziczącą QGraphicsView, dzięki czemu możemy obsłużyć zdarzenie resizeEvent. Obiekt zdarzenia to QResizeEvent zawierający obecny rozmiar okna pod metodą size. Mając wymiary okna skalujemy obrazek (qpixmap) za pomocą metody scaled i aktualizujemy obrazek przypisany do sceny.
RkBlog

PyQt, 15 December 2008,

Comment article