I am updating the color of the pen or even the pen of a QGraphicsLine object through a method programmed within a child class of a QGraphicsLine. The problem consists in when I set the new pen the line disappears when I call it from a thread.
import sys
from PyQt5.QtGui import QColor, QBrush, QPen, QPainter
from PyQt5.QtWidgets import QGraphicsScene, QGraphicsEllipseItem, QGraphicsSceneMouseEvent, \
QGraphicsSceneHoverEvent, QGraphicsLineItem, QApplication, QMainWindow, QGraphicsView, QToolBar, QAction
from threading import Thread
from time import sleep
from random import randint
class GraphicsLine(QGraphicsLineItem):
def __init__(self, x1: float, y1: float, x2: float, y2: float):
super(GraphicsLine, self).__init__(x1, y1, x2, y2)
pen = QPen(QColor(0, 0, 0))
pen.setWidth(5)
self.setPen(pen)
self.setZValue(5)
def change_color(self):
pen = QPen(QColor(randint(0, 255), randint(0, 255), randint(0, 255)))
pen.setWidth(5)
self.setPen(pen)
class GraphicsNode(QGraphicsEllipseItem):
def __init__(self, x: float, y: float, size: int):
super(GraphicsNode, self).__init__(x - size/2, y - size/2, size, size)
self.setAcceptHoverEvents(True)
self.setZValue(10)
brush = QBrush(QColor(0, 0, 0))
pen = QPen(QColor(0, 0, 0))
pen.setWidth(0)
self.setBrush(brush)
self.setPen(pen)
def mousePressEvent(self, event: QGraphicsSceneMouseEvent) -> None:
pass
def hoverEnterEvent(self, event: QGraphicsSceneHoverEvent) -> None:
self.setBrush(QColor(0, 255, 0))
def hoverLeaveEvent(self, event: QGraphicsSceneHoverEvent) -> None:
self.setBrush(QColor(0, 0, 0))
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.width = 600
self.height = 500
self.thread_stop = False
self.toolbar = QToolBar()
self.action_color = QAction('Change Color', self)
self.action_color.triggered.connect(self.__change_color)
self.toolbar.addAction(self.action_color)
self.action_stop = QAction('Stop Thread', self)
self.action_stop.triggered.connect(self.__stop_thread)
self.toolbar.addAction(self.action_stop)
self.addToolBar(self.toolbar)
self.scene = QGraphicsScene()
self.graphics_view = QGraphicsView(self.scene, self)
self.graphics_view.setRenderHints(QPainter.Antialiasing | QPainter.HighQualityAntialiasing)
self.graphics_view.setGeometry(0, 20, 600, 500)
self.__create_graphs()
self.show()
def __create_graphs(self):
self.nodes = [GraphicsNode(0, 0, 20), GraphicsNode(0, 100, 20)]
self.lines = [GraphicsLine(0, 0, 0, 100)]
for node in self.nodes:
self.scene.addItem(node)
for line in self.lines:
self.scene.addItem(line)
self.thread = Thread(target=self.__color_changer_thread)
self.thread.start()
def __color_changer_thread(self):
while not self.thread_stop:
for line in self.lines:
line.change_color()
sleep(5)
def __change_color(self):
for line in self.lines:
line.change_color()
def __stop_thread(self):
self.thread_stop = True
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
app.exec_()
The color of the object GraphicsLine is changed when clicking Action in ToolBar but, the thread makes the item not visible. If the thread is commented, then the Action bottom changes the color without trouble.
Thank you in advance.