Python PyQT QGraphics在后台线程中移动场景项
对不起,我的英语不好。 我需要更新背景线程中的图形场景。我需要线程在场景中移动我的矩形。但它不起作用,当线程开始时,rectagle隐藏在场景中,我看不到他的移动。只有当我在场景中的其他对象上移动鼠标时,我才能看到我的矩形是如何移动的。但若我改变线程中矩形的颜色,它就可以正常工作。我想做一个简单的客户机-服务器游戏,但我不明白如何从线程中移动场景中的对象。我知道,QGraphics场景不是线程安全的对象,但如何在没有计时器或事件的情况下在后台移动对象Python PyQT QGraphics在后台线程中移动场景项,python,pyqt,pyqt4,pyqt5,Python,Pyqt,Pyqt4,Pyqt5,对不起,我的英语不好。 我需要更新背景线程中的图形场景。我需要线程在场景中移动我的矩形。但它不起作用,当线程开始时,rectagle隐藏在场景中,我看不到他的移动。只有当我在场景中的其他对象上移动鼠标时,我才能看到我的矩形是如何移动的。但若我改变线程中矩形的颜色,它就可以正常工作。我想做一个简单的客户机-服务器游戏,但我不明白如何从线程中移动场景中的对象。我知道,QGraphics场景不是线程安全的对象,但如何在没有计时器或事件的情况下在后台移动对象 class MyGraphicRect2(Q
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_())
在主线程中运行图形部件,因此在其他线程中不应直接修改,这必须通过向主线程发出信号来完成,并且它位于图形部件更新的插槽中 下面的示例创建一个信号,该信号在次线程中每秒发出一次,它连接到
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_())
哇!它的作品!!!!非常感谢。为什么我没有想到这一点?毕竟,我之前做过线程之间的信号交换。再次非常感谢!!!!