总目录 >> PythonOCC入门进阶到实战(目前已更新入门篇、基础篇和进阶篇)
写在前面
刚开始的时候,只是比较多的关注功能层的实现,但是随着项目的推进,慢慢发现现有官方提供的主界面过于简单,再加上一些cad开发者也在不断地询问哪里有界面开发的教程,我想稍微总结一下之前做界面的经历,希望能够给大家一些启发和帮助。如果你觉得有用,关注下我,这就是对我最大的支持。
1.开发前提
首先要确认你已经安装了pyqt5,没有安装的,自行安装pip install pyqt5
关于使用pyside,wxpython的朋友,这方面我没太研究,但是本质应该差别不大。
本教程只是对主界面进行一个初步开发,如果你想拥有比较完善美观的界面,可以参考下这本书:pyqt5快速开发与实践
2.依赖文件 qtDisplay. py
将如下代码复制到名为qtDisplay. py,放到和主程序mainwindow(下面讲)同一文件夹
import logging
import os
import sys
from OCC.Display import OCCViewer
from PyQt5 import QtCore, QtGui, QtWidgets, QtOpenGL
# check if signal available, not available
# on PySide
HAVE_PYQT_SIGNAL = hasattr(QtCore, 'pyqtSignal')
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
log = logging.getLogger(__name__)
class point(object):
def __init__(self, obj=None):
self.x = 0
self.y = 0
if obj is not None:
self.set(obj)
def set(self, obj):
self.x = obj.x()
self.y = obj.y()
class qtBaseViewer(QtOpenGL.QGLWidget):
''' The base Qt Widget for an OCC viewer
'''
def __init__(self, parent=None):
QtOpenGL.QGLWidget.__init__(self, parent)
self._display = None
self._inited = False
# enable Mouse Tracking
self.setMouseTracking(True)
# Strong focus
self.setFocusPolicy(QtCore.Qt.WheelFocus)
# required for overpainting the widget
self.setAttribute(QtCore.Qt.WA_PaintOnScreen)
self.setAttribute(QtCore.Qt.WA_NoSystemBackground)
self.setAutoFillBackground(False)
def GetHandle(self):
''' returns an the identifier of the GUI widget.
It must be an integer
'''
win_id = self.winId() # this returns either an int or voitptr
if "%s" % type(win_id) == "<type 'PyCObject'>": # PySide
### with PySide, self.winId() does not return an integer
if sys.platform == "win32":
## Be careful, this hack is py27 specific
## does not work with python31 or higher
## since the PyCObject api was changed
import ctypes
ctypes.pythonapi.PyCObject_AsVoidPtr.restype = ctypes.c_void_p
ctypes.pythonapi.PyCObject_AsVoidPtr.argtypes = [
ctypes.py_object]
win_id = ctypes.pythonapi.PyCObject_AsVoidPtr(win_id)
elif not isinstance(win_id, int): # PyQt4 or 5
## below integer cast may be required because self.winId() can
## returns a sip.voitptr according to the PyQt version used
## as well as the python version
win_id = int(win_id)
return win_id
def resizeEvent(self, event):
if self._inited:
super(qtBaseViewer,self).resizeEvent(event)
self._display.OnResize()
class qtViewer3d(qtBaseViewer):
# emit signal when selection is changed
# is a list of TopoDS_*
if HAVE_PYQT_SIGNAL:
sig_topods_selected = QtCore.pyqtSignal(list)
def __init__(self, *kargs):
qtBaseViewer.__init__(self, *kargs)
self.setObjectName("qt_viewer_3d")
self._drawbox = False
self._zoom_area = False
self._select_area = False
self._inited = False
self._leftisdown = False
self._middleisdown = False
self._rightisdown = False
self._selection = None
self._drawtext = True
self._qApp = QtWidgets.QApplication.instance(