위젯은 자신을 다시 그릴때 paintEvent 함수를 호출합니다. 즉, 위젯에 무언가를 그리기에 가장 적당한 시점은 paintEvent입니다. 또한 여기에 그래픽 요소를 그리기 위해서 QPainter라는 API를 사용할 수 있습니다. 이 두가지를 조합하여 위젯을 상속받는 윈도우를 화면에 표시하고 이 윈도우에 원하는 그래픽 요소를 그리는 예를 살펴보겠습니다.
먼저 위젯을 상속받는 MyWindow라는 클래스를 하나 정의하는데, 이 클래스에는 앞서 언급한 paintEvent 함수를 재정의하고 있습니다.
import sys, random from PyQt5.QtWidgets import QWidget, QApplication from PyQt5.QtGui import QPainter, QColor, QFont, QPen, QBrush, QPainterPath from PyQt5.QtCore import Qt class MyWindow(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setGeometry(300, 300, 400, 400) self.setWindowTitle('QPainter를 이용한 그래픽스') self.show() def paintEvent(self, event): qp = QPainter() qp.begin(self) # 그리기 함수의 호출 부분 qp.end() if __name__ == '__main__': app = QApplication(sys.argv) ex = MyWindow() sys.exit(app.exec_())
위의 코드에서 20번째 줄에 그리기 함수를 호출함으로써 그 결과를 살펴볼 수 있는데요. 그리기 함수는 MyWindow 클래스의 맴버 함수로써 정의합니다. 먼저 텍스트를 그리는 함수입니다.
def drawText(self, event, qp): qp.setPen(QColor(0, 0, 0)) qp.setFont(QFont('나눔명조', 35)) qp.drawText(event.rect(), Qt.AlignCenter, '스산한 늦가을\n아니.. 초겨울인가?')
결과는 아래와 같습니다.
다음은 화면에 포인트를 찍는 함수입니다.
def drawPoints(self, event, qp): pen = QPen(Qt.gray, 3) qp.setPen(pen) size = self.size() for i in range(700): x = random.randint(1, size.width()-1) y = random.randint(1, size.height()-1) qp.drawPoint(x, y)
결과는 아래와 같습니다.
다음은 사각형을 그리는 함수입니다.
def drawRectangles(self, qp): col = QColor(0, 0, 0) col.setNamedColor('#d4d4d4') qp.setPen(col) qp.setBrush(QColor(200, 0, 0)) qp.drawRect(50, 50, 100, 100) qp.setBrush(QColor(255, 80, 0, 160)) qp.drawRect(150, 150, 100, 100) qp.setBrush(QColor(25, 0, 90, 200)) qp.drawRect(250, 250, 100, 100)
결과는 아래와 같습니다.
다음은 선을 그리는 함수입니다.
def drawLines(self, qp): pen = QPen(Qt.black, 3, Qt.SolidLine) qp.setPen(pen) qp.drawLine(50, 50, 350, 50) pen.setStyle(Qt.DashLine) qp.setPen(pen) qp.drawLine(50, 110, 350, 110) pen.setStyle(Qt.DashDotLine) qp.setPen(pen) qp.drawLine(50, 170, 350, 170) pen.setStyle(Qt.DotLine) qp.setPen(pen) qp.drawLine(50, 230, 350, 230) pen.setStyle(Qt.DashDotDotLine) qp.setPen(pen) qp.drawLine(50, 290, 350, 290) pen.setStyle(Qt.CustomDashLine) pen.setDashPattern([1, 4, 5, 4]) qp.setPen(pen) qp.drawLine(50, 350, 350, 350)
결과는 아래와 같습니다.
다음은 다양한 채움 스타일로 사각형을 그리는 함수입니다.
def drawBrushes(self, qp): brush = QBrush(Qt.SolidPattern) qp.setBrush(brush) qp.drawRect(20, 20, 110, 110) brush.setStyle(Qt.Dense1Pattern) qp.setBrush(brush) qp.drawRect(145, 20, 110, 110) brush.setStyle(Qt.Dense2Pattern) qp.setBrush(brush) qp.drawRect(270, 20, 110, 110) brush.setStyle(Qt.DiagCrossPattern) qp.setBrush(brush) qp.drawRect(20, 145, 110, 110) brush.setStyle(Qt.Dense5Pattern) qp.setBrush(brush) qp.drawRect(145, 145, 110, 110) brush.setStyle(Qt.Dense6Pattern) qp.setBrush(brush) qp.drawRect(270, 145, 110, 110) brush.setStyle(Qt.HorPattern) qp.setBrush(brush) qp.drawRect(20, 270, 110, 110) brush.setStyle(Qt.VerPattern) qp.setBrush(brush) qp.drawRect(145, 270, 110, 110) brush.setStyle(Qt.BDiagPattern) qp.setBrush(brush) qp.drawRect(270, 270, 110, 110)
결과는 아래와 같습니다.
다음은 베이지 곡선을 그리는 함수입니다.
def drawBezierCurve(self, qp): pen = QPen(Qt.black, 7) qp.setPen(pen) path = QPainterPath() path.moveTo(50, 50) path.cubicTo(200, 50, 50, 350, 350, 350) qp.drawPath(path)
결과는 아래와 같습니다.