def __init__(self, argv): self.plumbing_bridge = PlumbingBridge() self.procedures_bridge = ProceduresBridge(self.plumbing_bridge) self.daq_bridge = DAQBridge(self.plumbing_bridge) self.app = QApplication(argv) # ALL custom built QQuickItems have to be registered as QML objects in this way: qmlRegisterType(QMLVisualizationArea, 'VisualizationArea', 1, 0, 'VisualizationArea') self.app.setWindowIcon(QIcon(find_resource('icon.ico'))) self.app.setOrganizationName('Waterloo Rocketry') self.app.setOrganizationDomain('waterloorocketry.com') self.app.setApplicationName('Topside') self.qml_engine = QQmlEngine() context = self.qml_engine.rootContext() context.setContextProperty('plumbingBridge', self.plumbing_bridge) context.setContextProperty('proceduresBridge', self.procedures_bridge) self.main_window = self._make_main_window() # TODO(jacob): Currently we load these example files at startup # to make testing turnaround a bit faster. Figure out how to # make the application remember the last file opened, and open # that instead. self.plumbing_bridge.load_from_files([find_resource('example.pdl')]) self.procedures_bridge.load_from_file(find_resource('example.proc'))
def _qmlLoad( self, qmlfile ): engine = QQmlEngine() main_qml = Path(ATHENA_SRC_DIR) / 'qml' / qmlfile component = QQmlComponent(engine, main_qml.as_uri() ) if ( component.status() != QQmlComponent.Ready ): print ("Error loading QML:") print(component.errorString()) result = component.create() # Need to hold a reference in python to the QQmlComponent, or else # PySide2 will helpfully delete the material object along with it # after this function ends. self._qtrefs.append(component) return result
## and conditions see https://www.qt.io/terms-conditions. For further ## information use the contact form at https://www.qt.io/contact-us. ## ## GNU General Public License Usage ## Alternatively, this file may be used under the terms of the GNU ## General Public License version 3 as published by the Free Software ## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ## included in the packaging of this file. Please review the following ## information to ensure the GNU General Public License requirements will ## be met: https://www.gnu.org/licenses/gpl-3.0.html. ## ## $QT_END_LICENSE$ ## ############################################################################# import sys from helper import adjust_filename from PySide2.QtCore import QUrl from PySide2.QtGui import QGuiApplication from PySide2.QtQml import QQmlEngine, QQmlComponent app = QGuiApplication(sys.argv) engine = QQmlEngine() component = QQmlComponent(engine) # This should segfault if the QDeclarativeComponent has not QQmlEngine component.loadUrl(QUrl.fromLocalFile(adjust_filename('foo.qml', __file__)))
class Application: def __init__(self, argv): self.plumbing_bridge = PlumbingBridge() self.procedures_bridge = ProceduresBridge(self.plumbing_bridge) self.daq_bridge = DAQBridge(self.plumbing_bridge) self.app = QApplication(argv) # ALL custom built QQuickItems have to be registered as QML objects in this way: qmlRegisterType(QMLVisualizationArea, 'VisualizationArea', 1, 0, 'VisualizationArea') self.app.setWindowIcon(QIcon(find_resource('icon.ico'))) self.app.setOrganizationName('Waterloo Rocketry') self.app.setOrganizationDomain('waterloorocketry.com') self.app.setApplicationName('Topside') self.qml_engine = QQmlEngine() context = self.qml_engine.rootContext() context.setContextProperty('plumbingBridge', self.plumbing_bridge) context.setContextProperty('proceduresBridge', self.procedures_bridge) self.main_window = self._make_main_window() # TODO(jacob): Currently we load these example files at startup # to make testing turnaround a bit faster. Figure out how to # make the application remember the last file opened, and open # that instead. self.plumbing_bridge.load_from_files([find_resource('example.pdl')]) self.procedures_bridge.load_from_file(find_resource('example.proc')) def _make_main_window(self): # TODO(jacob): Should we move this code somewhere else (maybe # into a separate MainWindow class)? window = QMainWindow() vert_splitter = QSplitter(Qt.Vertical) vert_splitter.setChildrenCollapsible(False) horiz_splitter = QSplitter(Qt.Horizontal) horiz_splitter.setChildrenCollapsible(False) daq_widget = make_daq_widget(self.daq_bridge, self.plumbing_bridge) horiz_splitter.addWidget(daq_widget) plumb_widget = make_qml_widget(self.qml_engine, 'PlumbingPane.qml') plumb_widget.setMinimumWidth(600) plumb_widget.setMinimumHeight(600) horiz_splitter.addWidget(plumb_widget) proc_widget = make_qml_widget(self.qml_engine, 'ProceduresPane.qml') proc_widget.setMinimumWidth(400) proc_widget.setMinimumHeight(600) horiz_splitter.addWidget(proc_widget) vert_splitter.addWidget(horiz_splitter) controls_widget = make_qml_widget(self.qml_engine, 'ControlsPane.qml') controls_widget.setMinimumHeight(200) vert_splitter.addWidget(controls_widget) window.setCentralWidget(vert_splitter) file_menu = QMenu('&File') open_proc_action = QAction('Open Procedure Suite', window) open_proc_action.setShortcut(QKeySequence('Ctrl+O')) open_proc_action.triggered.connect( self.procedures_bridge.loadFromDialog) file_menu.addAction(open_proc_action) open_plumb_action = QAction('Open Plumbing Engine', window) open_plumb_action.setShortcut(QKeySequence('Ctrl+Shift+O')) open_plumb_action.triggered.connect( self.plumbing_bridge.loadFromDialog) file_menu.addAction(open_plumb_action) exit_action = QAction('Exit', window) exit_action.setShortcut(QKeySequence.Quit) exit_action.triggered.connect(window.close) file_menu.addAction(exit_action) window.menuBar().addMenu(file_menu) tools_menu = QMenu('&Tools') pdl_editor_action = QAction('PDL Editor', window) pdl_editor_action.setShortcut(QKeySequence('Ctrl+Shift+E')) pdl_editor_action.triggered.connect(self.launchPDLEditor) tools_menu.addAction(pdl_editor_action) window.menuBar().addMenu(tools_menu) return window @Slot() def launchPDLEditor(self): w = make_pdl_editor(self.main_window) w.show() def run(self): self.app.aboutToQuit.connect(self.shutdown) self.main_window.showMaximized() app_return_code = self.app.exec_() return app_return_code def shutdown(self): # NOTE(jacob): We explicitly `del` this to suppress a TypeError # that arises from the bridges getting destroyed before the QML # engine, causing QML references to go invalid. We attach this # cleanup to the aboutToQuit signal because app.exec_ is not # guaranteed to return, and therefore placing it immediately # after the app.exec_ call would not guarantee that this cleanup # routine runs. # For reference: https://bugreports.qt.io/browse/QTBUG-81247 del self.qml_engine
def __init__(self): super().__init__() self.engine = QQmlEngine() self.incubation = IncubationController() self.engine.setIncubationController(self.incubation)
def initialize(self, size: QSize, shareContext: QOpenGLContext) -> None: """ Initialize offscreen renderer. Args: size: The size of the area available for rendering. shareContext: OpenGL context used as a share context. Raises: RuntimeError: If the renderer has already been initialized. """ print(f'QmlOffscreenRenderer.initialize: {size}') if self.initialized: raise RuntimeError('Already initialized') format = QSurfaceFormat() format.setDepthBufferSize(16) format.setStencilBufferSize(8) context = QOpenGLContext() context.setFormat(format) context.setShareContext(shareContext) context.create() self.size = size self.context = context # Create offscreen surface with initialized format self._surface = surface = QOffscreenSurface() surface.setFormat(context.format()) surface.create() # Set up quick rendering self._control = control = QQuickRenderControl() self._window = window = QQuickWindow(control) self._engine = engine = QQmlEngine() if not engine.incubationController(): engine.setIncubationController(window.incubationController()) # Don't polish/sync/render immediately for better performance, use a timer self._renderTimer = renderTimer = QTimer() renderTimer.setSingleShot(True) renderTimer.setInterval(5) renderTimer.timeout.connect(self._onRenderTimer) self._syncTimer = syncTimer = QTimer() syncTimer.setSingleShot(True) syncTimer.setInterval(5) syncTimer.timeout.connect(self._onSyncTimer) syncTimer.destroyed.connect(self._onSyncTimerDestroyed) # Request to create frame buffer window.sceneGraphInitialized.connect(self._onSceneGraphInitialized) # Request to release frame buffer window.sceneGraphInvalidated.connect(self._onSceneGraphInvalidated) # Only render is needed control.renderRequested.connect(self._onRenderRequested) # Polish, sync & render control.sceneChanged.connect(self._onSceneChanged) self.initialized = True # Load QML component self._component = component = QQmlComponent(self._engine, self.qmlUrl) if component.isLoading(): component.statusChanged.connect(self._onComponentStatusChanged) else: self._attachRootItem()