質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

4844閲覧

PyQt5:QPainterが起動しない

Ykkykk

総合スコア140

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/11/14 01:41

編集2018/11/14 01:45

QPainter()インスタンスが起動しません。

Pyrhon3

1def paint(self, point): 2 painter = QPainter() 3 painter.begin(self) 4 painter.setPen(Qt.black) 5 painter.setBrush(QBrush(Qt.black), Qt.SolodPattern)) 6 painter.drawEllipse(QPointF(point[0], point[1]), 5, 5)

以上のようなコードを実行したところ、以下のようなエラーが出ました。

QWidget::paintEngine: Should no longer be called QPainter::begin: Paint device returned engine == 0, type: 1 QPainter::setPen: Painter not active

調べてみたところ、painter.begin()の引数として、QWidgetを渡すというような記述があり変更したところ、上記と同じエラーが出ました。
また、QPaintEventを使用する旨も見つけてはいるのですが、QPaintEventを使用した場合、上で書いたコードのように引数に点の座標を渡すことはできるのでしょうか?

上記のコードは、QPushButtonがクリックされた際に呼び出される点の値を計算する関数の中で呼び出されるものです。
QPaintEventを使用してもeventとして認識されませんでした。

ご教示いただけますと幸いです。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tiitoi

2018/11/14 04:35

QPainter を使って「何に」描画しようとしているのでしょうか?
Ykkykk

2018/11/14 04:39

QGraphicsSceneです。
guest

回答1

0

ベストアンサー

QGraphcisScene に描画する場合、描画するオブジェクトを QGraphicsItem として作成する必要があります。

手順

  1. QGraphicsItem を継承したクラスを作成する。
  2. paint(self, painter, option, widget) をオーバーライドする。
  3. paint() 関数に渡ってくる painter オブジェクトで描画する。

サンプルコード

python

1import sys 2 3import numpy as np 4from PyQt5.QtWidgets import * 5from PyQt5.QtGui import * 6from PyQt5.QtCore import * 7 8 9class StarGraphicsItem(QGraphicsItem): 10 def __init__(self, center, radius, parent=None): 11 super().__init__(parent) 12 self.center = center 13 self.radius = radius 14 15 def paint(self, painter, option, widget): 16 painter.setRenderHint(QPainter.Antialiasing) 17 # ペンとブラシを設定する。 18 painter.setPen(QPen(Qt.black, 3)) 19 painter.setBrush(Qt.yellow) 20 21 # ポリゴンを描画する。 22 poly = self.createShape() 23 painter.drawPolygon(poly) 24 25 def createShape(self): 26 '''星を表すポリゴンを生成する。 27 ''' 28 # 点を生成する。 29 num_points = 11 30 r = self.radius * np.where(np.arange(num_points) % 2 == 0, 0.5, 1.) # 半径 31 theta = np.linspace(0, 2 * np.pi, num_points) # 角度 32 xs = self.center[0] + r * np.sin(theta) # x 座標 33 ys = self.center[1] + r * np.cos(theta) # y 座標 34 35 # QPolygonF に格納する。 36 polygon = QPolygonF() 37 [polygon.append(QPointF(x, y)) for x, y in zip(xs, ys)] 38 39 return polygon 40 41 def boundingRect(self): 42 '''この図形を囲む矩形を返す。 43 ''' 44 45 return QRectF(self.center[0] - self.radius, 46 self.center[1] - self.radius, 47 self.radius * 2, self.radius * 2) 48 49 50class MainWindow(QMainWindow): 51 def __init__(self, parent=None): 52 super().__init__(parent) 53 self.setGeometry(100, 100, 500, 500) 54 55 # シーンを作成する。 56 starItem = StarGraphicsItem(center=(100, 100), radius=100) 57 self.scene = QGraphicsScene() 58 self.scene.addItem(starItem) 59 60 # QGraphicsView 61 graphicView = QGraphicsView() 62 graphicView.setScene(self.scene) 63 64 # Central Widget 65 central_widget = QWidget() 66 self.setCentralWidget(central_widget) 67 68 # Layout 69 layout = QVBoxLayout() 70 layout.addWidget(graphicView) 71 central_widget.setLayout(layout) 72 73 74if __name__ == '__main__': 75 app = QApplication(sys.argv) 76 main_window = MainWindow() 77 78 main_window.show() 79 sys.exit(app.exec_()) 80

イメージ説明

投稿2018/11/14 05:24

tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Ykkykk

2018/11/14 06:14

ご回答いただきありがとうございます。詳細なコードまでご提示いただき大変勉強になります。 QGraphicsItemを使用せずに描画することはできないということですね。 本当にありがとうございます。
tiitoi

2018/11/14 06:20

線、画像、楕円、長方形、点、ポリゴンなど基本的な図形を表す QGraphicsItem はすでに用意されているので、複雑な図形もそれらを組み合わせれば描画できると思います。 例えば回答の例では、自分で QGraphicsItem を継承して作っていますが、ポリゴンの描画は QGraphicsPolygonItem を使っても同じことができます。
Ykkykk

2018/11/14 06:27 編集

描画したいのは単純な円なのですが、addItemで一括して描画するのではなく、scene上に一つ一つ描画していきたいと思い、QGraphicsItemを使用しないで描画しようとしておりました。現在は、QGraphicsSceneのaddEllipseメソッドを使用しているのですが、アンチエイリアシングができずにガタガタになってしまうため、QPainterを使用できないのかと思っていた次第です。
tiitoi

2018/11/14 07:25 編集

全アイテムにアンチエイリアス有効にしたいのであれば、QGraphicsView の setRenderHint() を設定すれよいです。 この設定は各アイテムで QPainter が描画する際に使用されます。 graphicView.setRenderHint(QPainter.Antialiasing)
Ykkykk

2018/11/14 07:31

加えてご回答くださり、ありがとうございます。 なるほど、QGraphicsViewにもsetRenderHintがあったのですね…。完全に見落としておりました。 QGraphicsViewでアンチエイリアスを有効にすることができました。 本当にありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問