2017-11-02 22 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

こんにちは、感謝、1つの質問に答えるが、私はQGraphicsEventsとQWidgetsの間のイベントの通信にどこに行こうとしているの良いアイデアを与えるために上記のコードを更新しました。ここでQWraphicsSceneとQWindowの間で信号を接続すると、QLabelを現在のターミナルに印刷されているテキストで更新できますか?つまり、クリックするとQLabelが「Circle Clicked!」に変わります。 – cvw76

+0

@ cvw76。私はあなたに基づいて2番目の例を追加しました。 (PS:この回答に合格とマークされている、つまりティックシンボルをクリックすると感謝しています) – ekhumoro

+0

優秀!ラムダはかなりエレガントで、私は複雑になりつつありました。これは私の小さなアプリで実装しようとしていた問題を完全に解決します。本当にありがとう!!私は完璧に答えたように印をつけた。 – cvw76

関連する問題