2017-11-02 33 views
1

두 번 클릭했을 때 QGraphicsItem에서 신호를 내보내 주 창에서 위젯을 변경하려고합니다. graphics-scene/-item은 emit() 메서드를 제공하지 않지만이 작업을 수행 할 대체 방법이 있는지 궁금합니다. 아래 코드는 QGraphicsView 클래스 내에서 항목을 두 번 클릭 할 때 터미널에 인쇄하는 함수입니다. 대신 슬롯/신호로 만들 수 있습니까 (QGraphicsItem이 신호/슬롯을 지원하지 않는 경우)?PySide/PyQT5 : QGraphicsItem에서 신호를 내보내는 방법은 무엇입니까?

import sys 
from PySide.QtCore import * 
from PySide.QtGui import * 

class MyFrame(QGraphicsView): 
    def __init__(self, parent = None): 
     super(MyFrame, self).__init__(parent) 

     scene = QGraphicsScene() 
     self.setScene(scene) 
     self.setFixedSize(500, 500) 

     pen = QPen(QColor(Qt.green)) 
     brush = QBrush(pen.color().darker(150)) 

     item = scene.addEllipse(0, 0, 45, 45, pen, brush) 
     item.setPos(0,0) 

    def mouseDoubleClickEvent(self, event): 
     print("Circle Clicked!") 
     # this double click event prints to terminal but how to setup 
     # signal/slot to update the QWidget QLabel text instead? 

class Example(QWidget): 
    def __init__(self): 
     super(Example, self).__init__() 
     self.initUI() 

    def initUI(self):   
     hbox = QHBoxLayout(self) 
     top = QLabel("Double Click Green Circle (Howto change this QWidget Label with signals?)") 
     bottom = MyFrame() 

     splitter = QSplitter(Qt.Vertical) 
     splitter.addWidget(top) 
     splitter.addWidget(bottom) 

     hbox.addWidget(splitter) 
     self.setLayout(hbox) 
     self.setGeometry(0, 0, 500, 600) 
     self.show() 

def main(): 
    app = QApplication(sys.argv) 
    ex = Example() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 
+0

후 '() self.scene을 맞춤 QGraphicsScene'' '서브 클래스에 itemDoubleClicked' 신호를 정의한다. itemDoubleClicked.emit()'항목에서. – ekhumoro

+0

예가 있습니까? – cvw76

+0

'클래스 GS (QGraphicsScene) : itemDoubleClicked = QtCore.pyqtSignal()' – ekhumoro

답변

0

다음은 그래픽 항목에서 신호를 내보내는 한 가지 방법을 보여주는 간단한 예입니다. 이 QGraphicsScene의 서브 클래스에서 사용자 정의 신호를 정의하고 다음을 방출하는 그래픽 항목의 scene() 방법을 사용

import sys 
from PySide import QtCore, QtGui 

class GraphicsScene(QtGui.QGraphicsScene): 
    itemDoubleClicked = QtCore.Signal(object) 

class GraphicsRectangle(QtGui.QGraphicsRectItem): 
    def mouseDoubleClickEvent(self, event): 
     self.scene().itemDoubleClicked.emit(self) 

class Window(QtGui.QWidget): 
    def __init__(self): 
     super(Window, self).__init__() 
     self.view = QtGui.QGraphicsView() 
     self.scene = GraphicsScene(self) 
     self.view.setScene(self.scene) 
     layout = QtGui.QVBoxLayout(self) 
     layout.addWidget(self.view) 
     for i in range(1, 4): 
      self.scene.addItem(GraphicsRectangle(50 * i, 50 * i, 20, 20)) 
     self.scene.itemDoubleClicked.connect(self.handleItemDoubleClicked) 

    def handleItemDoubleClicked(self, item): 
     print(item.boundingRect()) 

if __name__ == '__main__': 

    app = QtGui.QApplication(sys.argv) 
    window = Window() 
    window.setGeometry(600, 100, 300, 200) 
    window.show() 
    sys.exit(app.exec_()) 

UPDATE을 :

다음

가의 코드를 기반으로 예를 들어 당신의 문제. 기본 아이디어는 동일합니다 : 사용 가능한 QObject (이 경우 그래픽보기)에서 사용자 정의 신호를 정의한 다음이를 사용하여 두 번 클릭 알림을 내 보냅니다.

import sys 
from PySide.QtCore import * 
from PySide.QtGui import * 

class MyFrame(QGraphicsView): 
    itemDoubleClicked = Signal(object) 

    def __init__(self, parent=None): 
     super(MyFrame, self).__init__(parent) 
     scene = QGraphicsScene() 
     self.setScene(scene) 
     self.setFixedSize(500, 500) 
     for i, color in enumerate('red blue green'.split()): 
      pen = QPen(QColor(color)) 
      brush = QBrush(pen.color().darker(150)) 
      item = scene.addEllipse(i * 50, i * 50, 45, 45, pen, brush) 
      item.setData(0, color.upper()) 

    def mouseDoubleClickEvent(self, event): 
     item = self.itemAt(event.pos()) 
     if item is not None: 
      self.itemDoubleClicked.emit(item) 

class Example(QWidget): 
    def __init__(self): 
     super(Example, self).__init__() 
     self.initUI() 

    def initUI(self): 
     hbox = QHBoxLayout(self) 
     top = QLabel('Double Click a Circle') 
     bottom = MyFrame() 
     bottom.itemDoubleClicked.connect(
      lambda item, top=top: 
       top.setText('Double Clicked: %s' % item.data(0))) 
     splitter = QSplitter(Qt.Vertical) 
     splitter.addWidget(top) 
     splitter.addWidget(bottom) 
     hbox.addWidget(splitter) 
     self.setLayout(hbox) 
     self.setGeometry(0, 0, 500, 600) 
     self.show() 

def main(): 
    app = QApplication(sys.argv) 
    ex = Example() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 
+0

안녕하세요, 고마워, 하나의 질문에 대답하지만 위의 코드를 QGraphicsEvents와 QWidgets 사이의 통신 이벤트로 이동하려고하는 위치에 대한 더 나은 아이디어를 제공하도록 업데이트했습니다. QWindow 내부에 중첩 된 QGraphicsScene 사이의 신호를 어떻게 연결하여 터미널에 현재 인쇄되고있는 텍스트로 QLabel을 업데이트 할 수 있습니까? 즉, 클릭하면 QLabel이 "Circle Clicked!"로 변경됩니다. – cvw76

+0

@ cvw76. 나는 당신에 기초한 두 번째 예제를 추가했다. (추신 :이 대답을 허용 된 것으로 표시했으면 즉, 눈금 기호를 클릭하면 감사하게 생각합니다.) – ekhumoro

+0

우수! 람다는 꽤 우아하고 복잡한 방법으로 가고 있었는데, 이것은 내 작은 앱에서 구현하려고했던 문제를 완벽하게 해결합니다. 정말 고마워!! 나는 완벽하게 대답 한 것으로 표시했다. – cvw76