PyQT QGraphicScene在后台线程中移动项目

时间:2017-06-02 12:16:49

标签: python pyqt pyqt4 pyqt5

抱歉我的英语不好。 我需要在后台线程中更新图形场景。我需要线程在场景上移动我的矩形。但它没有用,当线程开始时,rectagle隐藏在场景中,我无法看到他的举动。只有当我在场景中移动其他物体时,我才能看到我的矩形是如何移动的。但是如果我在线程中改变矩形的颜色,它工作正常。我想制作简单的客户端 - 服务器游戏,但我不了解如何从线程移动场景中的对象。我知道,QGraphics场景不是线程安全的对象,但如何在没有计时器或事件的情况下在后台移动对象?

class Product < ApplicationRecord
  validates :name, presence: true      

  has_many :product_locations

  accepts_nested_attributes_for :product_locations
end

1 个答案:

答案 0 :(得分: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_())