基于QGraphcisview做了个绘图软件,上面用QGraphicsTextItem显示了几个文本图元,在用线程定时器定时刷新文本内容时(方法:self.setPlainText(newText)),提示:QObject: Cannot create children for a parent that is in a different thread.;
但是调用self.setRotation(self._angle)可以旋转文本,
改变文本值与旋转实现方法有何不同呢,self.setPlainText是重新赋值,不是新建呀。
这是因为Qt的GUI部分不是线程安全的。只有主线程才能更改UI元素。如果你想在非主线程中更改UI元素,你需要使用Qt提供的线程信号和槽机制。
在你的情况下,调用 self.setRotation(self._angle) 不会引发错误,因为它只更改了QGraphicsTextItem的旋转属性,并不涉及到文本图元在场景中的父对象。而调用 self.setPlainText(newText) 则涉及到重新创建文本图元,因此会引发错误。
为了解决这个问题,你可以在主线程中使用QTimer来定时更改文本图元的属性。在定时器的回调函数中,使用信号和槽机制将更新后的文本信息发送给主线程,然后在主线程中更新QGraphicsTextItem的文本属性。具体实现方式如下:
from PyQt5.QtCore import QObject, pyqtSignal, QTimer
from PyQt5.QtGui import QGraphicsTextItem
class MyTextItem(QGraphicsTextItem):
update_text = pyqtSignal(str)
def __init__(self, text, parent=None):
super().__init__(text, parent)
self.timer = QTimer(self)
self.timer.timeout.connect(self.updateText)
self.timer.start(1000) # 1秒钟刷新一次
def updateText(self):
# 在这里更新文本信息
new_text = "Hello World"
self.update_text.emit(new_text)
class MainWindow(QObject):
def __init__(self):
super().__init__()
self.textItem = MyTextItem("Hello", parent=None)
self.textItem.update_text.connect(self.updateText)
def updateText(self, new_text):
# 在这里更新QGraphicsTextItem的文本属性
self.textItem.setPlainText(new_text)
在这个示例中,我们创建了一个名为 MyTextItem 的QGraphicsTextItem的子类,并使用QTimer定期更新文本信息。在定时器回调函数中,我们发出了一个信号,将新的文本信息发送到主线程。然后在主线程中,我们连接了 update_text 信号到 updateText 槽函数中,并在 updateText 函数中更新了QGraphicsTextItem的文本属性。
“Devil组”引证GPT后的撰写:
我现在是用class MyTextItem(QGraphicsTextItem):创建了一个文本类,
在主页面窗口中调用文本类建立了10个文本图元,
然后在主窗体中建立了一个线程定时器,在其中定时分别修改10个文本图元的文字。
不是在文本类中用定时器,
每个文本图元要能分别赋予不同的值,定时器中要用遍历查找各图元并赋予相应的不同值(图元及对应值存储于一个字典中)