読者です 読者をやめる 読者になる 読者になる

bravo's blog

マルチプラットフォームGUIツールキット+軽量言語であるPyQtのプログラミングとか

PyQtでのグラフィックス その1 (QWidgetに直接描画する)

PyQt PyQt5 Python Python3

PyQtでの描画処理について

PyQtでグラフィックス処理をするには、主に以下のような方法があります。

  • QWidgetの描画処理をオーバーライド:単純なグラフィック描画や自作のウィジェットとして描画する
  • QGraphicsItemの使用:Qtに備わった複数のグラフィックを扱うフレームワーク
  • OpenGLを使用:OpenGLの命令を使う場合(執筆時点では未調査、存在確認だけです。)

QWidgetに直接描画する

paintEventメソッドのオーバーライド

QWidgetやQWidgetから派生したクラスでは、実際に描画する処理がpaintEvent()メソッドで行われます。 また、描画内容を変えたい時にはupdate()メソッドを呼び出すと、QWidget側が適切に更新します。

実際の描画は、painteEvent()内でQPainterやQPainterPathのインスタンスを生成し、描画命令をするだけです。 単純に線を引くdrawLine()や、連続した線を引くdrawPolyline()、長方形を描画するdrawRect()、などがあります。 描画命令は種類が豊富なので、公式のAPIが載ったドキュメントを参照ください。 検索サイト等で「QPainter (バージョン番号)」や「QPainterPath (バージョン番号)」で検索すればすぐに出てくると思います。

正方形を描画するサンプル

赤い線と黄色い塗りの正方形を描画します。

import sys

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class Widget(QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setPen(Qt.red)
        painter.setBrush(Qt.yellow)
        painter.drawRect(10, 10, 100, 100)

def main():
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    w.raise_()
    app.exec_()

if __name__ == '__main__':
    main()

実行結果
f:id:bravo:20160207080309p:plain

マウスで描画するサンプル

真っ白なQWidgetを用意し、マウスでドラッグしている間に線を描画します。

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class Widget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.px = None
        self.py = None
        self.points = []
        self.psets = []

    def mousePressEvent(self, event):
        self.points.append(event.pos())
        self.update()

    def mouseMoveEvent(self, event):
        self.points.append(event.pos())
        self.update()

    def mouseReleaseEvent(self, event):
        self.pressed = False
        self.psets.append(self.points)
        self.points = []
        self.update()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setPen(Qt.NoPen)
        painter.setBrush(Qt.white)
        painter.drawRect(self.rect())

        painter.setPen(Qt.black)

        # draw historical points
        for points in self.psets:
            painter.drawPolyline(*points)

        # draw current points
        if self.points:
            painter.drawPolyline(*self.points)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    w.raise_()
    sys.exit(app.exec_())

実行結果(描画部分はマウスで操作しています)
f:id:bravo:20160207082701p:plain

広告