2017-10-25 4 views
0

私はPyQtベクトルペインティングを学ぼうとしています。現在、私は推測するpaintEvent()メソッドに情報を渡そうとしています。他のメソッドを呼び出す必要があります:PyQt5がkeyPressEvent()でpaintEvent()をトリガー

基本ブロック(ここではdrawFundBlock()メソッドに異なる数字をペイントしようとしています。 )。コードは、右矢印が「押された」か「下」かをチェックしようとしています。数字が押されている場合(単に「5」を描くようになっている)、その番号をその基本ブロックの特定の領域に描画します。しかし、私はQPainterを動作させるように見えません。 paintEvent()オーバーライドメソッドを2回呼び出すようです(なぜ?)。 update()メソッドを提案している人もいますが、 "fundblock"か "number"のどちらを描画するかを決定するpaintEvent()に引数を渡す方法はわかりません。コードではデモ用にupdate()を使用していますが、これは単に行を移動するだけですが、すでに追加されている行は残っているはずです。

助けが必要ですか?

# Test QPainter etc. 

from PyQt5.QtWidgets import QWidget, QApplication 
from PyQt5.QtGui import QPainter, QPen, QColor, QFont 
from PyQt5.QtCore import Qt, QPoint, pyqtSignal, QRect 
import sys 

class Example(QWidget): 

    paintTrigger = pyqtSignal() 

    def __init__(self): 
     super().__init__() 
     self.initUI() 
     self.ydist = 15 
     self.eveType = "drawBlock" 
     self.currentRegion = QRect(50,50,50,80) 
     #self.paintTrigger[self.eveType].connect(lambda:self.paintEvent()) 

     self.x0=5 
     self.x1=25 
     self.y0=5 
     self.y1=25 

    def initUI(self): 
     self.setGeometry(300,300,280,270) 
     self.setWindowTitle('Painter training') 
     self.show() 

    # How to pass info here, which type of drawing should be done (block or number)? 
    def paintEvent(self,event): 
     qp = QPainter(self) 
     qp.begin(self) 
     self.drawFundBlock(qp) 
     qp.end() 

    def drawFundBlock(self,qp): 
     pen = QPen(Qt.black, 2, Qt.SolidLine) 
     pen.setStyle(Qt.DashLine) 

     qp.setPen(pen) 
     for i in range(1,10): 
      #qp.drawLine(0,i*self.ydist,40,i*self.ydist) 
      qp.drawLine(self.x0,i*self.y0,self.x1,self.y0*i) 

     #notePoint=QPoint(200,200) 
     #qp.drawText(notePoint,"5") 

    def drawNumber(self,qp,notePoint): 
     pen = QPen(Qt.black,2,Qt.SolidLine) 
     #qp.setPen(QColor(200,200,200)) 
     qp.setPen(pen) 
     qp.setFont(QFont('Arial', 10)) 
     qp.drawText(notePoint,"5") 

    def nextRegion(self): 
     self.x0=self.x0+30 
     self.x1=self.x1+30 
     self.y0=self.y0+30 
     self.y1=self.y1+30 

    def keyPressEvent(self,event): 
     # Did the user press a button?? 
     gey=event.key() 
     if gey == Qt.Key_M: 
      print("Key 'm' pressed!") 
     elif gey == Qt.Key_Right: 
      print("Right key pressed!, call drawFundBlock()") 
      #self.paintTrigger["drawBlock"].emit() 
      #self.paintEvent() 
      self.update() 
      self.nextRegion() 

     elif gey == Qt.Key_5: 
      print("#5 pressed, call drawNumber()") 
      #self.paintTrigger["drawNo"].emit() 


if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    ex = Example() 
    sys.exit(app.exec_()) 
+0

私もself.paintEvent(に接続されているpyqtSignal()を作成しようとしました)が、再び、それは動作しないだろうと私はあなたがいけpaintEvent – HammieTime

+0

に関連する情報を渡すことはできませんpaintEventを直接呼び出す場合は、update()を使用してください。 – eyllanesc

+0

必要なことを正しく説明してください。前の図面を維持しますか? – eyllanesc

答えて

0

QPaintEventを直接呼び出すことはできません、我々はupdate()を通してそれを行う必要があり、これは必要なときに内部的にそれを呼び出すの世話をします。

いつもQPaintEventと呼ばれていますが、それは先ほどの図面のメモリを節約しないように描画する場所です。簡単な解決策は先にペイントしたものを保存するQPixmapそのQPixmapでウィジェットをペイントします。

もう一つは、以下の2つの命令が等価であるということです。

1.


painter = QPainter(some_QPaintDevice) 

2.


painter = QPainter() 
painter.begin(some_QPaintDevice) 

どちらの方法は、塗装されようとしているオブジェクトを渡すのに役立つ、とあなたのケースでは、あなたは2回、同じウィジェットを割り当てています。私はこの方法がself.funcで満たされる必要がある方法drawBackgroundを、提案した図面を容易にするために、

、最初のパラメータは、関数の名前と第二QPainter以外に必要とされるパラメータを持つ辞書でなければなりません。

コード

class Example(QWidget): 
    def __init__(self): 
     super().__init__() 
     self.mModified = True 
     self.initUI() 
     self.currentRegion = QRect(50, 50, 50, 80) 
     self.x0 = 5 
     self.x1 = 25 
     self.y0 = 5 
     self.y1 = 25 
     self.mPixmap = QPixmap() 
     self.func = (None, None) 

    def initUI(self): 
     self.setGeometry(300, 300, 280, 270) 
     self.setWindowTitle('Painter training') 
     self.show() 

    def paintEvent(self, event): 
     if self.mModified: 
      pixmap = QPixmap(self.size()) 
      pixmap.fill(Qt.white) 
      painter = QPainter(pixmap) 
      painter.drawPixmap(0, 0, self.mPixmap) 
      self.drawBackground(painter) 
      self.mPixmap = pixmap 
      self.mModified = False 

     qp = QPainter(self) 
     qp.drawPixmap(0, 0, self.mPixmap) 

    def drawBackground(self, qp): 
     func, kwargs = self.func 
     if func is not None: 
      kwargs["qp"] = qp 
      func(**kwargs) 

    def drawFundBlock(self, qp): 
     pen = QPen(Qt.black, 2, Qt.SolidLine) 
     pen.setStyle(Qt.DashLine) 

     qp.setPen(pen) 
     for i in range(1, 10): 
      qp.drawLine(self.x0, i * self.y0, self.x1, self.y0 * i) 

    def drawNumber(self, qp, notePoint): 
     pen = QPen(Qt.black, 2, Qt.SolidLine) 
     qp.setPen(pen) 
     qp.setFont(QFont('Arial', 10)) 
     qp.drawText(notePoint, "5") 

    def nextRegion(self): 
     self.x0 += 30 
     self.x1 += 30 
     self.y0 += 30 
     self.y1 += 30 

    def keyPressEvent(self, event): 
     gey = event.key() 
     self.func = (None, None) 
     if gey == Qt.Key_M: 
      print("Key 'm' pressed!") 
     elif gey == Qt.Key_Right: 
      print("Right key pressed!, call drawFundBlock()") 
      self.func = (self.drawFundBlock, {}) 
      self.mModified = True 
      self.update() 
      self.nextRegion() 
     elif gey == Qt.Key_5: 
      print("#5 pressed, call drawNumber()") 
      self.func = (self.drawNumber, {"notePoint": QPoint(100, 100)}) 
      self.mModified = True 
      self.update() 
+0

ありがとうございました!それは動作するようです。今私はPixmap /バックグラウンドの使い方を理解しなければなりません。 – HammieTime

+0

@HammieTime私の回答が正しいとマークするのに役立ちますが、それを行う方法はわかっている場合は、次のリンクを確認してください:https://stackoverflow.com/tour – eyllanesc

関連する問題