pythonocc-demos
pythonocc-demos copied to clipboard
core_visualization_overpaint_viewer example crash
core_visualization_overpaint_viewer.py crashes at QtGui.QPainter(self)
Same for both Pyside2 5.15.1 and PyQt5 5.12.3.
Can you please elaborate (trace/os/pyocc version)
Windows 10, pyocc 7.4.0
It prints this:
INFO:OCC.Display.backend:backend loaded: qt-pyqt5
###### 3D rendering pipe initialisation #####
Display3d class initialization starting ...
Aspect_DisplayConnection created.
Graphic_Driver created.
V3d_Viewer created.
AIS_InteractiveContext created.
V3d_View created
WNT window created.
Display3d class successfully initialized.
########################################
Process finished with exit code -1073740771 (0xC000041D)
It shows only the box, stays a couple seconds frozen then closes.
I see the paintEngine solves the crash. But it still does not show any bubbles ?
Area zoom doesn't draw the selection box on top of the view.
QRubberBand seems to be able to draw selection rectangle on top of the view. But any other shape we draw with QPainter in paintEvent does not shown.
Here the examples:
Current behaviour example
import sys
from PySide2.QtWidgets import QApplication, QMainWindow, QRubberBand, QStyleFactory
from PySide2.QtGui import QColor, QPainter, QBrush, QPaintEvent, QResizeEvent, QMouseEvent
from PySide2.QtCore import Qt, QPoint, QRect, QSize
from PySide2.QtOpenGL import QGLWidget
from OCC.Core.Quantity import Quantity_Color, Quantity_TOC_RGB, Quantity_NOC_BLACK
from OCC.Core.V3d import V3d_ZBUFFER, V3d_XposYnegZpos
from OCC.Core.Aspect import Aspect_TOTP_RIGHT_LOWER
from OCC.Core.AIS import AIS_Shaded
from OCC.Core.Visualization import Display3d
class OCCRubberBand(QRubberBand):
def __init__(self, rubber_band_shape, parent=None):
super().__init__(rubber_band_shape, parent)
self.setStyle(QStyleFactory.create("windows"))
def paintEvent(self, event: QPaintEvent):
painter = QPainter(self)
painter.drawRect(event.rect())
painter.end()
class OCCWidget(QGLWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.origin = QPoint()
self.rubber_band = OCCRubberBand(QRubberBand.Rectangle, self)
self.setMouseTracking(True)
self.setAutoFillBackground(False)
self.setFocusPolicy(Qt.StrongFocus)
self.setAttribute(Qt.WA_NativeWindow, True)
self.setAttribute(Qt.WA_PaintOnScreen, True)
self.setAttribute(Qt.WA_NoSystemBackground, True)
display3d = Display3d()
display3d.Init(self.winId())
self.display3d = display3d
self.v3d_viewer = display3d.GetViewer()
self.v3d_viewer.SetDefaultLights()
self.v3d_viewer.SetLightOn()
self.v3d_view = display3d.GetView()
self.v3d_view.SetBackgroundColor(Quantity_TOC_RGB, 0.34, 0.34, 0.34)
self.v3d_view.TriedronDisplay(Aspect_TOTP_RIGHT_LOWER, Quantity_Color(Quantity_NOC_BLACK), 0.1, V3d_ZBUFFER)
self.v3d_view.SetProj(V3d_XposYnegZpos)
self.ais_context = display3d.GetContext()
self.ais_context.SetAutomaticHilight(True)
self.ais_context.SetDisplayMode(AIS_Shaded, False)
self.prs3d_drawer = self.ais_context.DefaultDrawer()
self.prs3d_drawer.SetFaceBoundaryDraw(True)
self.is_resized = False
def paintEngine(self):
return None
def resizeEvent(self, event: QResizeEvent):
self.is_resized = True
def paintEvent(self, event: QPaintEvent):
if self.is_resized:
self.is_resized = False
self.v3d_view.MustBeResized()
else:
self.v3d_view.Redraw()
# Does not draw !
self.makeCurrent()
painter = QPainter(self)
self.swapBuffers()
# This should draw a white filled rectangle.
rect = QRect(QPoint(100, 100), QPoint(painter.device().width()-100, painter.device().height()-100))
brush = QBrush()
brush.setColor(QColor(255, 255, 255))
brush.setStyle(Qt.SolidPattern)
painter.fillRect(rect, brush)
painter.end()
self.doneCurrent()
# Does not draw !
def mousePressEvent(self, event: QMouseEvent):
self.origin = event.pos()
self.rubber_band.setGeometry(QRect(self.origin, QSize()))
self.rubber_band.show()
def mouseMoveEvent(self, event: QMouseEvent):
if self.rubber_band.isVisible():
self.rubber_band.setGeometry(QRect(self.origin, event.pos()).normalized())
self.update()
def mouseReleaseEvent(self, event: QMouseEvent):
if self.rubber_band.isVisible():
self.rubber_band.hide()
class MainWindow(QMainWindow):
def __init__(self, parent=None):
self.q_app = QApplication.instance()
if self.q_app is None:
self.q_app = QApplication(sys.argv)
super().__init__(parent=parent)
self.setWindowTitle("PyOCC - Overprint example")
self.resize(1024, 768)
self.occ_widget = OCCWidget()
self.setCentralWidget(self.occ_widget)
def event_loop(self):
self.show()
return self.q_app.exec_()
if __name__ == "__main__":
window = MainWindow()
sys.exit(window.event_loop())
Desired behaviour example
import sys
from PySide2.QtWidgets import QApplication, QMainWindow, QRubberBand, QStyleFactory
from PySide2.QtGui import QColor, QPainter, QBrush, QPaintEvent, QResizeEvent, QMouseEvent
from PySide2.QtCore import Qt, QPoint, QRect, QSize
from PySide2.QtOpenGL import QGLWidget
class OCCRubberBand(QRubberBand):
def __init__(self, rubber_band_shape, parent=None):
super().__init__(rubber_band_shape, parent)
self.setStyle(QStyleFactory.create("windows"))
def paintEvent(self, event: QPaintEvent):
painter = QPainter(self)
painter.drawRect(event.rect())
painter.end()
class OCCWidget(QGLWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.origin = QPoint()
self.rubber_band = OCCRubberBand(QRubberBand.Rectangle, self)
self.setMouseTracking(True)
self.setAutoFillBackground(False)
self.setFocusPolicy(Qt.StrongFocus)
self.setAttribute(Qt.WA_NativeWindow, True)
self.setAttribute(Qt.WA_PaintOnScreen, True)
self.setAttribute(Qt.WA_NoSystemBackground, True)
# # If we override this method it will not draw the filled rectangles in paintEvent.
# # But if we do not override while using Display3d then at "painter = QPainter(self)" it crashes.
# def paintEngine(self):
# return None
def paintEvent(self, event):
painter = QPainter(self)
device = painter.device()
w = device.width()
h = device.height()
brush = QBrush()
brush.setColor(QColor(0, 0, 200))
brush.setStyle(Qt.SolidPattern)
painter.fillRect(QRect(QPoint(), QPoint(w, h)), brush)
rect = QRect(QPoint(100, 100), QPoint(painter.device().width()-100, painter.device().height()-100))
brush = QBrush()
brush.setColor(QColor(255, 255, 255))
brush.setStyle(Qt.SolidPattern)
painter.fillRect(rect, brush)
painter.end()
def mousePressEvent(self, event):
self.origin = event.pos()
self.rubber_band.setGeometry(QRect(self.origin, QSize()))
self.rubber_band.show()
def mouseMoveEvent(self, event):
if self.rubber_band.isVisible():
self.rubber_band.setGeometry(QRect(self.origin, event.pos()).normalized())
self.update()
def mouseReleaseEvent(self, event):
if self.rubber_band.isVisible():
self.rubber_band.hide()
class MainWindow(QMainWindow):
def __init__(self, parent=None):
self.q_app = QApplication.instance()
if self.q_app is None:
self.q_app = QApplication(sys.argv)
super().__init__(parent=parent)
self.setWindowTitle("PyOCC - Overprint example")
self.resize(1024, 768)
self.occ_widget = OCCWidget()
self.setCentralWidget(self.occ_widget)
def event_loop(self):
self.show()
return self.q_app.exec_()
if __name__ == "__main__":
window = MainWindow()
sys.exit(window.event_loop())