PyQtクラスを追加しやすくするEmacs Lisp
Emacs LispでPyQtのクラスを作る部分を省力化
PyQtプログラミングをやっていると、クラスを追加するのに毎回同じような記述をするのが非常にかったるくなってきます。普通にコピペでも良いのですが、以下のようなEmacs lispでもう少しEmacsらしく使えるようにしてみました。
- .emacsに以下のコードを追記してEmacsを再起動などで.emacsをリロードします。
- py-modeの状態で
M-x pyqt-new-class
で呼び出すとミニバッファにNew Qt class:
と表示されますので、新しいクラスの名前を入力してEnterを押します。 - 次にミニバッファに
Base Qt class:
と表示されますので、直前に入力したクラスの親クラスを入力してEnterを押します。 - 追加したいクラスの
__init__()
まで含めたコードが入力されます。
この状態でも特に不自由はしてないのですが、インデント幅が固定だったりと改善の余地はあります。
.emacsに追記するコード
(add-hook 'py-mode-hook '(lambda () (defun pyqt-new-class (class-name base-class-name) (interactive "sNew Qt class: \nsBase Qt class: ") (insert (format "class %s(%s):\n def __init__(self, parent=None):\n super(%s, self).__init__(parent)\n" class-name base-class-name class-name))) ))
実行画面
関数を呼び出し
追加クラス名を入力
追加クラスの親クラス名を入力
このように入力されます。
- 作者: Mark Summerfield
- 出版社/メーカー: Prentice Hall
- 発売日: 2007/10/18
- メディア: Kindle版
- この商品を含むブログを見る
PyQtでの2Dグラフィックス その1 (QWidgetに直接描画する)
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()
実行結果
マウスで描画するサンプル
真っ白な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_())
実行結果(描画部分はマウスで操作しています)