QEntity
, созданный в методе, вызываемом сигналом, не работает должным образом.
Вызов метода setEnabled(True)
или setEnabled(False)
при QEntity
не оказывает влияния.
Ниже приведен рабочий пример:
import numpy as np
from PySide2.QtCore import Qt, QObject, Slot, Signal, QThread
from PySide2.QtGui import QVector3D
from PySide2.Qt3DCore import Qt3DCore
from PySide2.QtWidgets import (
QApplication, QWidget, QVBoxLayout, QHBoxLayout, QCheckBox, QPushButton,
)
from PySide2.Qt3DExtras import Qt3DExtras
class Worker(QObject):
@Slot()
def do_work(self):
self.sig_done.emit(None)
self.sig_stopped.emit()
sig_done = Signal(object)
sig_stopped = Signal()
class Sphere(Qt3DCore.QEntity):
def __init__(self, parent):
super().__init__(parent)
self.data = []
self.mesh = Qt3DExtras.QSphereMesh()
self.mesh.setRadius(.5)
self.transform = Qt3DCore.QTransform()
location = np.random.rand(3) * 10
self.transform.setTranslation(QVector3D(*location))
self.material = Qt3DExtras.QPhongMaterial(self)
self.addComponent(self.material)
self.addComponent(self.mesh)
self.addComponent(self.transform)
def toggle(self):
if self.isEnabled():
self.setEnabled(False)
else:
self.setEnabled(True)
def setEnabled(self, is_enabled):
print("Hello from Sphere!", is_enabled)
super().setEnabled(is_enabled)
class Spheres(Qt3DCore.QEntity):
def __init__(self, parent):
super().__init__(parent)
self.container = [Sphere(self) for _ in range(10)]
def setEnabled(self, is_enabled):
print("Hello from Sphere Container!", is_enabled)
super().setEnabled(is_enabled)
class Window(Qt3DExtras.Qt3DWindow):
def __init__(self):
super().__init__()
self.resize(300, 300)
# Root entity
self.root_entity = Qt3DCore.QEntity()
# Camera
self.cameraEntity = self.camera()
self.camera().lens().setPerspectiveProjection(45.0, 16.0 / 9.0, 0.1, 1000.0)
self.camera().setPosition(QVector3D(20.0, 20.0, 20.0))
self.camera().setUpVector(QVector3D(0, 1, 0))
self.camera().setViewCenter(QVector3D(0, 0, 0))
# For camera controls
self.camera_controller = Qt3DExtras.QFirstPersonCameraController(self.root_entity)
self.camera_controller.setCamera(self.camera())
self.spheres = None
self.setRootEntity(self.root_entity)
def load(self):
self.spheres = Spheres(self.root_entity)
class Widget(QWidget):
def __init__(self):
super().__init__()
self.view = Window()
self.container = self.createWindowContainer(self.view)
hLayout = QHBoxLayout(self)
self.vLayout = QVBoxLayout()
self.vLayout.setAlignment(Qt.AlignTop)
hLayout.addWidget(self.container, 1)
hLayout.addLayout(self.vLayout)
self.cb_spheres = None
self.cb_single_sphere = None
# ***** These lines cause problems:
self._thread = QThread()
self._worker = Worker()
self._worker.moveToThread(self._thread)
self._worker.sig_stopped.connect(self._thread.quit)
self._worker.sig_done.connect(self.load)
self._thread.started.connect(self._worker.do_work)
self._thread.start()
# *****
@Slot()
def load(self):
self.view.load()
self.cb_spheres = QCheckBox(self)
self.cb_spheres.setChecked(True)
self.cb_spheres.setText("All spheres")
self.vLayout.addWidget(self.cb_spheres)
spheres = self.view.spheres
def func():
spheres.setEnabled(not spheres.isEnabled())
self.cb_spheres.stateChanged.connect(func)
self.cb_single_sphere = []
for i in range(10):
self.cb_single_sphere.append(QCheckBox(self))
self.cb_single_sphere[-1].setChecked(True)
self.cb_single_sphere[-1].setText("Sphere {}".format(i))
self.vLayout.addWidget(self.cb_single_sphere[-1])
self.cb_single_sphere[-1].stateChanged.connect(spheres.container[i].toggle)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Widget()
w.show()
w.resize(1200, 800)
sys.exit(app.exec_())
Он работает, когда я заменяю строки между *****
на self.load()
.
И не работает, когда эти строки заменяются:
self.btn = QPushButton("Load", self)
self.btn.clicked.connect(self.load)
self.vLayout.addWidget(self.btn)
Редактировать: ни одна из них не работает при замене этих строк на:
self.timer = QTimer()
self.timer.setSingleShot(True)
self.timer.setInterval(1000)
self.timer.timeout.connect(self.load)
self.timer.start()
Есть ли способ исправить это?