2017-06-02 14 views
0

私の悪い英語のために申し訳ありません。 バックグラウンドスレッドでグラフィックシーンを更新する必要があります。私は糸が私の矩形をシーン上に動かす必要がある。しかし、それは動作しません、スレッドが開始され、rectagleがシーンに隠れている、と私は彼の動きを見ることはできません。私が他のオブジェクトのシーンにマウスで移動した場合にのみ、私はどのように矩形が動くかを見ることができます。しかし、私はスレッドの色の矩形を変更する場合、それは正常に動作します。シンプルなクライアントサーバーゲームを作ってみたいですが、スレッドからシーン上のオブジェクトをどのように動かすのか分かりません。 QGraphics Sceneはスレッドセーフなオブジェクトではありませんが、タイマーやイベントなしでオブジェクトをバックグラウンドで移動させるにはどうしたらいいですか?メインスレッドでPyQT QGraphicSceneはバックグラウンドスレッドでアイテムを移動します

class MyGraphicRect2(QGraphicsItem): 
    def __init__(self, x, y, width, height): 
     super().__init__() 
     self.x = x 
     self.y = y 
     self.width = width 
     self.height = height 
     self.setPos(self.x, self.y) 
     self.color = QColor('red') 

     # self.setToolTip('Test') 

     self.setAcceptDrops(True) 
     self.setCursor(Qt.OpenHandCursor) 
     self.setFlag(QGraphicsItem.ItemIsSelectable, True) 
     self.setFlag(QGraphicsItem.ItemIsMovable, True) 
     self.setFlag(QGraphicsItem.ItemIsFocusable, True) 
     self.setAcceptHoverEvents(True) 


     s = Shadow() 
     b = Blur() 
     c = ColorChange() 
     self.setGraphicsEffect(s) 
     # self.setGraphicsEffect(c) 

     # self.setGraphicsEffect(b) 

    def setColor(self, color): 
     self.color = QColor(color) 

    def boundingRect(self): 
     return QRectF(self.x, self.y, self.width, self.height) 

    def paint(self, painter, options, widget): 
     painter.setPen(QPen(QColor('black'))) 
     painter.setBrush(self.color) 
     painter.drawRect(self.x, self.y, self.width, self.height) 


class MoveThread(QThread): 
    def __init__(self,object,scene,view): 
     super().__init__() 
     self.object=object 
     self.scene=scene 
     self.view=view 
    def run(self): 
     for i in range(1,10): 
      time.sleep(1) 
      self.object.moveBy(30,0) 
      print(self.object.pos().x()) 
      #self.object.update() 
      self.view.updateSceneRect(QRectF(0,0,800,800)) 


     #for color in ['green','white','black','magenta','yellow']: 
     # time.sleep(1) 
     # self.object.setColor(color) 
     # self.object.update() 


class MyGraphicScene(QMainWindow): 
    def __init__(self): 
     super().__init__() 
     self.rect=QRectF(0,0,800,800) 
     self.Scene=QGraphicsScene(self.rect) 
     self.View=QGraphicsView() 
     self.View.setCacheMode(QGraphicsView.CacheNone) 
     self.sceneConfig() 

    def sceneConfig(self): 
         self.Scene.setBackgroundBrush(QBrush(QColor('yellow'),Qt.SolidPattern))) 

    item=MyGraphicItem(30,30,100,100) 
    self.item1=MyGraphicRect2(100,100,100,100) 
    self.Scene.addItem(item) 
    self.Scene.addItem(self.item1) 
    line=QGraphicsLineItem(80,38,84,38) 
    self.Scene.addItem(line) 
    self.View.setScene(self.Scene) 

def displayUI(self): 
    print('Is scene active', self.Scene.isActive()) 
    self.setCentralWidget(self.View) 
    self.th=MoveThread(self.item1,self.Scene,self.View) 
    self.th.start() 
    self.resize(1000,1000) 
    self.show() 


app=QApplication(sys.argv) 

m=MyGraphicScene() 

sys.exit(app.exec_()) 

答えて

0

直接変更すべきではない他のスレッド内にグラフィック部分を実行し、これがメインスレッドに信号を発することによって行わなければならず、それは、そのスロットにあるグラフィック一部が更新された場合であります。

次の例では、セカンダリスレッドで毎秒発行され、updatePositionスロットに接続する信号を作成し、オブジェクトがどこに移動するかを示します。

class MyGraphicRect2(QGraphicsItem): 
    def __init__(self, x, y, width, height): 
     super().__init__() 
     self.x = x 
     self.y = y 
     self.width = width 
     self.height = height 
     self.setPos(self.x, self.y) 
     self.color = QColor('red') 

     self.setAcceptDrops(True) 
     self.setCursor(Qt.OpenHandCursor) 
     self.setFlag(QGraphicsItem.ItemIsSelectable, True) 
     self.setFlag(QGraphicsItem.ItemIsMovable, True) 
     self.setFlag(QGraphicsItem.ItemIsFocusable, True) 
     self.setAcceptHoverEvents(True) 

    def setColor(self, color): 
     self.color = QColor(color) 

    def boundingRect(self): 
     return QRectF(self.x, self.y, self.width, self.height) 

    def paint(self, painter, options, widget): 
     painter.setPen(QPen(QColor('black'))) 
     painter.setBrush(self.color) 
     painter.drawRect(self.x, self.y, self.width, self.height) 


class MoveThread(QThread): 
    s = pyqtSignal(float, float) 
    def __init__(self): 
     super().__init__() 
    def run(self): 
     for i in range(1,10): 
      time.sleep(1) 
      self.s.emit(30,0) 


class MyGraphicScene(QMainWindow): 
    def __init__(self): 
     super().__init__() 
     self.rect=QRectF(0,0,800,800) 
     self.Scene=QGraphicsScene(self.rect) 
     self.View=QGraphicsView() 
     self.View.setCacheMode(QGraphicsView.CacheNone) 
     self.sceneConfig() 
     self.displayUI() 

    def sceneConfig(self): 
     self.Scene.setBackgroundBrush(QBrush(QColor('yellow'),Qt.SolidPattern)) 

     self.item1=MyGraphicRect2(100,100,100,100) 
     self.Scene.addItem(self.item1) 
     line=QGraphicsLineItem(80,38,84,38) 
     self.Scene.addItem(line) 
     self.View.setScene(self.Scene) 

    def updatePosition(self, x, y): 
     self.item1.moveBy(x, y) 

    def displayUI(self): 
     print('Is scene active', self.Scene.isActive()) 
     self.setCentralWidget(self.View) 
     self.th=MoveThread() 
     self.th.s.connect(self.updatePosition) 
     self.th.start() 
     self.resize(1000,1000) 
     self.show() 

import sys 
app=QApplication(sys.argv) 

m=MyGraphicScene() 

sys.exit(app.exec_()) 
+0

WOW !!その作品!!!!ありがとうございました!!!!!なぜそんな考えが私の心に来なかったのですか?結局のところ、私はスレッド間の信号交換の前にやっています。再び多くの感謝!!!! –

関連する問題