2017-10-25 3 views
0

PyQt 벡터 페인팅을 배우려고합니다. 현재 나는 다른 메소드를 호출해야한다고 생각하는 paintEvent() 메소드에 정보를 전달하려고 노력하고 있습니다.PyQt5가 keyPressEvent()를 사용하여 paintEvent()를 트리거합니다.

기본 블록 (여기서는 drawFundBlock() 메소드에 다른 숫자를 그려야합니다.). 이 코드는 오른쪽 화살표가 눌려져 있는지를 확인하려고 시도하고 있습니다.> drawFundamental 블록이고 숫자가 눌려지면 (이제는 단순히 "5"를 그려야합니다), 그 숫자를 그 기본 블록의 특정 영역에 그릴 것입니다. 하지만 나는 QPainter를 작동시킬 수없는 것 같습니다. paintEvent() 메서드를 두 번 지금 호출하는 것 같습니다 (왜?). 어떤 사람들은 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

코드, 그것은 작동하지 않을 것입니다 그리고 당신은 안 – HammieTime

+0

를 paintEvent하기 위해 관련 정보를 전달할 수 없습니다 paintEvent를 직접 호출하면 update()를 통해 수행해야합니다. – eyllanesc

+0

원하는대로 정확하게 설명하십시오. 이전 도면을 유지 보수 하시겠습니까? – eyllanesc

답변

0

QPaintEvent 직접 호출 할 수 없습니다, 우리는 update()를 통해 수행해야합니다,이 필요할 때 내부적으로 호출 처리됩니다.

때마다 QPaintEvent이 깨끗한이라고하는 것은 그렇게는 이전 도면의 메모리를 저장하지 않습니다 그릴 예정이다 공간, 간단한 솔루션은 이전에 다음 색칠 한 내용을 저장할 위치를 먼저 QPixmap를 칠하는 것입니다 위젯을 QPixmap으로 그립니다.

또 다른 일이 다음 2 개 명령어는 동일하다는 것을 :

1.


painter = QPainter(some_QPaintDevice) 

2.


painter = QPainter() 
painter.begin(some_QPaintDevice) 
,536,

두 가지 방법 모두 오브젝트가 페인트 될 위치를 전달하며, 사용자의 경우 동일한 위젯을 두 번 할당합니다. I이 방법 drawBackground에게 제시 한 도면을 용이

는,이 방법 self.func 채워질 필요가 첫번째 파라미터 함수의 이름과 QPainter 제외 필요한 파라미터를 상기 제 2 사전이어야한다.

나는 또한 다시 self.paintEvent() 만에 연결되어있는 pyqtSignal()를 만들려고

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/background 사용법을 이해해야합니다. – HammieTime

+0

@HammieTime 내 대답을 올바르게 표시해주세요.하지만 어떻게해야하는지 알고 있다면 다음 링크를 확인하십시오. https://stackoverflow.com/tour – eyllanesc

관련 문제