Stronę tą wyświetlono już: 7474 razy
Klasa QPainter umożliwia rysowanie np. po oknie programu czy kontrolki, jak również rysowanie po bitmapie a także drukowanie. Klasa ta zawiera zestaw metod umożliwiających rysowanie różnego typu prymitywów, takich jak:
- punkty;
- linie;
- linie łamane;
- wielokąty;
- prostokąty;
- elipsy;
- tekst
- i inne nie wymienione przeze mnie.
Rysowanie po oknie programu
Bardzo często do rysowania po oknie programu wykorzystuje się zdarzenie paintEvent. Zdarzenie to jest wywoływane gdy następuje konieczność odświeżenia (odrysowania) całego lub wyznaczonego obszaru okna programu (co wiąże się z optymalizacją). Program wywołuje to zdarzenie, gdy jakaś część okna wymaga odrysowania. Dzieje się tak np. przy zmianie rozmiaru okna, minimalizacji i maksymalizacji. Oto prosty przykład wykorzystania tego zdarzenia do narysowania okręgu:
Każda zmiana rozmiaru okna spowoduje jego odrysowanie co z kolei sprawi, że okrąg narysowany będzie zawsze rysował się na środku tegoż okna. Gdyby zrobić mały eksperyment i cały proces rysowania wykonać jednorazowo np. po kliknięciu w oknie programu lewym przyciskiem myszy to okazałoby się, że każde odświeżenie okna wymazywałoby tak narysowany element. Z tego względu proces rysowania powinien odbywać się pod zdarzeniem paintEvent, natomiast zapamiętywanie obiektów, które powinny być rysowane powinno być realizowane oddzielnie.
Rysowanie po obiekcie klasy QImage
Możliwe jest również rysowanie po utworzonym obiekcie klasy QImage. Oto przykład:
Powyższy prosty przykład umożliwia rysowanie jednym pędzlem po bitmapie poprzez wciśnięcie i przytrzymanie lewego przycisku myszy wraz z przemieszczeniem kursora myszy. Jest to realizowane w zdarzeniu mouseMoveEvent. Sam proces rysowania bitmapy w oknie programu jest z kolei realizowany w zdarzeniu paintEvent. Warto dodać, że domyślnie każda kontrolka wywołuje zdarzenie mouseMoveEvent tylko wtedy, gdy któryś z przycisków myszy zostanie wciśnięty. Stan ten można zmodyfikować korzystając z metody setMouseTracking wchodzącej w skład każdej kontrolki czy też każdego okna programu.
Metody rysujące klasy QPainter
Oto lista metod rysujących wchodzących w skład klasy QPainter:
drawArc - rysuje łuk eliptyczny:
painter.drawArc( 100, // położenie lewej krawędzi prostokąta opisującego elipsę na osi x 100, // położenie lewej krawędzi prostokąta opisującego elipsę na osi y 50, // długość prostokąta opisującego elipsę 50, // wysokość prostokąta opisującego elipsę 20 * 16, // kąt początkowy wyrażony w 1 / 16 części stopnia jako liczba całkowita (int) 90 * 16 // kąt przyrostu łuku wyrażony w 1 / 16 części stopnia jako liczba całkowita (int) );drawChord - rysuje odcinek elipsy:
painter.drawChord( 100, // położenie lewej krawędzi prostokąta opisującego elipsę na osi x 100, // położenie lewej krawędzi prostokąta opisującego elipsę na osi y 50, // długość prostokąta opisującego elipsę 50, // wysokość prostokąta opisującego elipsę 20 * 16, // kąt początkowy wyrażony w 1 / 16 części stopnia jako liczba całkowita (int) 90 * 16 // kąt przyrostu odcinka wyrażony w 1 / 16 części stopnia jako liczba całkowita (int) );drawConvexPolygon - rysuje wielokąt wykorzystując tablicę punktów:
static const QPointF points[4] = { QPointF(10.0, 10.0), QPointF(110.0, 110.0), QPointF(110.0, 10.0), QPointF(10.0, 110.0) }; painter.drawConvexPolygon( points, // tablica punktów 4 // liczba początkowych punktów do uwzględnienia przy rysowaniu );Można również wykorzystać obiekt klasy QPolygon lub QPolygonF do rysowania wielokątów.
drawEllipse - rysuje elipsę (a nawet i koło):
painter.drawEllipse( 100, // położenie lewej krawędzi prostokąta opisującego elipsę na osi x 100, // położenie lewej krawędzi prostokąta opisującego elipsę na osi y 50, // długość prostokąta opisującego elipsę 100 // wysokość prostokąta opisującego elipsę );drawGlyphRun - rysowanie obiektu klasy QGlyphRun dającego dostęp do znaku danej czcionki;
- drawImage - rysowanie bitmapy np. obiektu klasy QImage:
QRectF target(10.0, 20.0, 80.0, 60.0); // prostokąt docelowy QRectF source(0.0, 0.0, 70.0, 40.0); // prostokąt wyciąganego fragmentu grafiki QImage image(":/images/myImage.png"); // ładowanie grafiki z zasobów programu painter.drawImage(target, image, source); // rysowanie
drawLine - rysowanie linii:
painter.drawLine( 10, // x1 10, // y1 300, // x2 300 // y2 );drawLines - rysuje linie;
drawPath - rysuje ścieżkę z możliwością wykorzystania krzywych Bezier-a:
QPainterPath path; path.moveTo(20, 80); path.lineTo(20, 30); path.cubicTo(80, 0, 50, 50, 80, 80); painter.drawPath(path);drawPicture - rysuje obiekt klasy QPicture;
drawPie - rysuje wycinek elipsy:
painter.drawPie( 100, // położenie lewej krawędzi prostokąta opisującego elipsę na osi x 100, // położenie lewej krawędzi prostokąta opisującego elipsę na osi y 50, // promień na osi x 50, // promień na osi y 20 * 16, // kąt początkowy wyrażony w 1 / 16 części stopnia jako liczba całkowita (int) 90 * 16 // kąt przyrostu wyrażony w 1 / 16 części stopnia jako liczba całkowita (int) );drawPixmap - rysuje obiekt klasy QPixmap;
drawPixmapFragments;
drawPoint - rysowanie punktu;
drawPoints - rysowanie punktów;
drawPolygon - rysowanie wielokąta:
static const QPointF points[4] = { QPointF(10.0, 10.0), QPointF(110.0, 110.0), QPointF(110.0, 10.0), QPointF(10.0, 110.0) }; painter.drawPolygon( points, // tablica punktów 4 // liczba początkowych punktów do uwzględnienia przy rysowaniu );Można również wykorzystać obiekt klasy QPolygon lub QPolygonF do rysowania wielokątów.
- drawPolyline - rysuje linię łamaną:
static const QPointF points[3] = { QPointF(10.0, 80.0), QPointF(20.0, 10.0), QPointF(80.0, 30.0), }; painter.drawPolyline(points, 3);
Można również wykorzystać obiekt klasy QPolygon lub QPolygonF do rysowania linii łamanej.
drawRect - rysowanie prostokąta;
drawRects - rysowanie prostokątów;
drawRoundedRect - rysowanie prostokąta z zaokrąglonymi narożnikami;
drawStaticText - rysowanie tekstu zapisanego w obiekcie klasy QStatiText;
drawText - rysuje tekst zapisany w obiekcie klasy QString;
fillPath - wypełnia ścieżkę wybranym deseniem będącym obiektem klasy QBrush;
fillRect - wypełnia prostokąt wybranym deseniem będącym obiektem klasy QBrush
Pędzle i desenie
Pędzle to obiekty klasy QPen, które opisują właściwości linii rysowanych przez obiekt klasy QPainter. W celu wykorzystania pędzla obiekt klasy QPainter musi wywołać metodę begin a następnie za pomocą metody setPen można ustawić bieżący pędzel rysowania. Każdy pędzel ma do dyspozycji podstawowy zestaw styli, które można wyświetlić za pomocą poniższego kodu:
Wynik działania powyższego kodu pokazany został na poniższym rysunku.
Istnieje jeszcze jeden styl Qt::CustomDashLine, który umożliwia ustawienie własnego stylu kreskowania w następujący sposób:
Powyższy kod narysuje linię o odcinkach długości 10, 2, 2, 2, 2, 10, 2, 2... i odstępach równych 2.
Podobnie rzecz ma się z deseniami opisującymi sposób wypełnienia obiektów rysowanych. Desenie są obiektami klasy QBrush i tak jak w przypadku pędzli można dany deseń ustawić jako bieżący za pomocą metody setBrush obiektu klasy QPainter. Każde wypełnienie ma dostępną listę standardowych wzorców, oto przykładowy kod generujący podgląd takich deseni:
Na poniższym rysunku pokazany został efekt działania powyższego kodu.
Obiekt QBrush ma do dyspozycji style, umożliwiające tworzenie wypełnień gradientowych. Oto spis takich styli:
- Qt::NoBrush - brak wypełnienia;
- Qt::ConicalGradientPattern - wypełnienie gradientem stożkowym;
- Qt::RadialGradientPattern - wypełnienie gradientem radialnym;
- Qt::LinearGradientPattern - wypełnienie gradientem liniowym
Istnieje też styl Qt::TexturePattern umożliwiający ustawienie jako wypełnienia swojej własnej grafiki za pomocą metody setTexture.
Operacje macierzowe
Za pomocą odpowiednich mtod klasy QPainter można:
- skalować za pomocą metody scale;
- przemieszczać za pomocą metody translate;
- obracać za pomocą metody rotate;
- obracać, skalować, przemieszczać a nawet i więcej za pomocą metody setWorldTransform i obiektu klasy QTransform.
Pierwsze trzy metody można sobie wyobrazić jak działają, natomiast ja pokażę jak można wykorzystując klasę QTransform obracać rysowany obiekt o kąt względem dowolnego punktu. Oto przykład:
Wynik działania powyższego kodu widoczny jest na poniższym rysunku.