mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-04-09 10:10:55 +02:00
Compare commits
16 Commits
tomcat/pro
...
feat/gener
| Author | SHA1 | Date | |
|---|---|---|---|
| 7cdc99fba0 | |||
| 2a24a64f82 | |||
| fb043f86d1 | |||
| f7e46e5d8b | |||
| b37ed0d45c | |||
| bfb3da0104 | |||
| 6623aa83df | |||
| 2c816345b5 | |||
| 4a36f4f717 | |||
| 2693ce4c38 | |||
| acb50febf1 | |||
| dc9c1ec099 | |||
| 167a1e8f00 | |||
| 0517d9f3e9 | |||
| 93a410bbf6 | |||
| 30aacadbf0 |
BIN
bec_widgets/assets/BEC-Dark.png
Normal file
BIN
bec_widgets/assets/BEC-Dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
@@ -1,9 +0,0 @@
|
||||
from .motor_movement import (
|
||||
MotorControlApp,
|
||||
MotorControlMap,
|
||||
MotorControlPanel,
|
||||
MotorControlPanelAbsolute,
|
||||
MotorControlPanelRelative,
|
||||
MotorCoordinateTable,
|
||||
MotorThread,
|
||||
)
|
||||
|
||||
0
bec_widgets/examples/general_app/__init__.py
Normal file
0
bec_widgets/examples/general_app/__init__.py
Normal file
96
bec_widgets/examples/general_app/general_app.py
Normal file
96
bec_widgets/examples/general_app/general_app.py
Normal file
@@ -0,0 +1,96 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
import qdarktheme
|
||||
from qtpy.QtGui import QActionGroup
|
||||
from qtpy.QtWidgets import QStyle
|
||||
from qtpy.QtCore import QSize
|
||||
from qtpy.QtGui import QIcon
|
||||
from qtpy.QtWidgets import QApplication, QMainWindow
|
||||
|
||||
from bec_widgets.examples.general_app.web_links import BECWebLinksMixin
|
||||
from bec_widgets.utils.ui_loader import UILoader
|
||||
|
||||
|
||||
class BECGeneralApp(QMainWindow):
|
||||
def __init__(self, parent=None):
|
||||
super(BECGeneralApp, self).__init__(parent)
|
||||
ui_file_path = os.path.join(os.path.dirname(__file__), "general_app.ui")
|
||||
self.load_ui(ui_file_path)
|
||||
|
||||
self.resize(1280, 720)
|
||||
|
||||
self.ini_ui()
|
||||
|
||||
def ini_ui(self):
|
||||
self._setup_icons()
|
||||
self._hook_menubar_docs()
|
||||
self._hook_theme_bar()
|
||||
|
||||
def load_ui(self, ui_file):
|
||||
loader = UILoader(self)
|
||||
self.ui = loader.loader(ui_file)
|
||||
self.setCentralWidget(self.ui)
|
||||
|
||||
def _hook_menubar_docs(self):
|
||||
# BEC Docs
|
||||
self.ui.action_BEC_docs.triggered.connect(BECWebLinksMixin.open_bec_docs)
|
||||
# BEC Widgets Docs
|
||||
self.ui.action_BEC_widgets_docs.triggered.connect(BECWebLinksMixin.open_bec_widgets_docs)
|
||||
# Bug report
|
||||
self.ui.action_bug_report.triggered.connect(BECWebLinksMixin.open_bec_bug_report)
|
||||
|
||||
def change_theme(self, theme):
|
||||
qdarktheme.setup_theme(theme)
|
||||
|
||||
def _setup_icons(self):
|
||||
help_icon = QApplication.style().standardIcon(QStyle.SP_MessageBoxQuestion)
|
||||
bug_icon = QApplication.style().standardIcon(QStyle.SP_MessageBoxInformation)
|
||||
computer_icon = QIcon.fromTheme("computer")
|
||||
|
||||
self.ui.action_BEC_docs.setIcon(help_icon)
|
||||
self.ui.action_BEC_widgets_docs.setIcon(help_icon)
|
||||
self.ui.action_bug_report.setIcon(bug_icon)
|
||||
|
||||
self.ui.central_tab.setTabIcon(0, computer_icon)
|
||||
|
||||
def _hook_theme_bar(self):
|
||||
# Make actions checkable
|
||||
self.ui.action_light.setCheckable(True)
|
||||
self.ui.action_dark.setCheckable(True)
|
||||
|
||||
# Create an action group to make sure only one can be checked at a time
|
||||
theme_group = QActionGroup(self)
|
||||
theme_group.addAction(self.ui.action_light)
|
||||
theme_group.addAction(self.ui.action_dark)
|
||||
theme_group.setExclusive(True)
|
||||
|
||||
# Connect the actions to the theme change method
|
||||
self.ui.action_light.triggered.connect(lambda: self.change_theme("light"))
|
||||
self.ui.action_dark.triggered.connect(lambda: self.change_theme("dark"))
|
||||
|
||||
self.ui.action_dark.trigger()
|
||||
|
||||
|
||||
def main(): # pragma: no cover
|
||||
from qtpy import PYSIDE6
|
||||
|
||||
if not PYSIDE6:
|
||||
print(
|
||||
"PYSIDE6 is not available in the environment. UI files with BEC custom widgets are runnable only with PySide6."
|
||||
)
|
||||
return
|
||||
import bec_widgets
|
||||
|
||||
module_path = os.path.dirname(bec_widgets.__file__)
|
||||
app = QApplication(sys.argv)
|
||||
icon = QIcon()
|
||||
icon.addFile(os.path.join(module_path, "assets", "BEC-Dark.png"), size=QSize(48, 48))
|
||||
app.setWindowIcon(icon)
|
||||
main_window = BECGeneralApp()
|
||||
main_window.show()
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
main()
|
||||
380
bec_widgets/examples/general_app/general_app.ui
Normal file
380
bec_widgets/examples/general_app/general_app.ui
Normal file
@@ -0,0 +1,380 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1718</width>
|
||||
<height>1139</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<property name="tabShape">
|
||||
<enum>QTabWidget::TabShape::Rounded</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="central_tab">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="vscode">
|
||||
<attribute name="icon">
|
||||
<iconset theme="QIcon::ThemeIcon::Computer"/>
|
||||
</attribute>
|
||||
<attribute name="title">
|
||||
<string>Visual Studio Code</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="VSCodeEditor" name="vscode"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Tab 2</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1718</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuHelp">
|
||||
<property name="title">
|
||||
<string>Help</string>
|
||||
</property>
|
||||
<addaction name="action_BEC_docs"/>
|
||||
<addaction name="action_BEC_widgets_docs"/>
|
||||
<addaction name="action_bug_report"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuTheme">
|
||||
<property name="title">
|
||||
<string>Theme</string>
|
||||
</property>
|
||||
<addaction name="action_light"/>
|
||||
<addaction name="action_dark"/>
|
||||
</widget>
|
||||
<addaction name="menuTheme"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<widget class="QDockWidget" name="dock_scan_control">
|
||||
<property name="windowTitle">
|
||||
<string>Scan Control</string>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>2</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="ScanControl" name="scan_control"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QDockWidget" name="dock_status_2">
|
||||
<property name="windowTitle">
|
||||
<string>BEC Service Status</string>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>2</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents_3">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="BECStatusBox" name="bec_status_box_2">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="flags">
|
||||
<set>ItemIsSelectable|ItemIsDragEnabled|ItemIsDropEnabled|ItemIsUserCheckable</set>
|
||||
</property>
|
||||
</item>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QDockWidget" name="dock_queue">
|
||||
<property name="windowTitle">
|
||||
<string>Scan Queue</string>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>2</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents_4">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="BECQueue" name="bec_queue">
|
||||
<row/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
<item row="0" column="0"/>
|
||||
<item row="0" column="1"/>
|
||||
<item row="0" column="2"/>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<action name="action_BEC_docs">
|
||||
<property name="icon">
|
||||
<iconset theme="QIcon::ThemeIcon::DialogQuestion"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>BEC Docs</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_BEC_widgets_docs">
|
||||
<property name="icon">
|
||||
<iconset theme="QIcon::ThemeIcon::DialogQuestion"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>BEC Widgets Docs</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_bug_report">
|
||||
<property name="icon">
|
||||
<iconset theme="QIcon::ThemeIcon::DialogError"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Bug Report</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_light">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Light</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_dark">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dark</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>BECQueue</class>
|
||||
<extends>QTableWidget</extends>
|
||||
<header>bec_queue</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ScanControl</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>scan_control</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>VSCodeEditor</class>
|
||||
<extends>QWebEngineView</extends>
|
||||
<header>vscode</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>BECStatusBox</class>
|
||||
<extends>QTreeWidget</extends>
|
||||
<header>bec_status_box</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QWebEngineView</class>
|
||||
<extends></extends>
|
||||
<header location="global">QtWebEngineWidgets/QWebEngineView</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
15
bec_widgets/examples/general_app/web_links.py
Normal file
15
bec_widgets/examples/general_app/web_links.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import webbrowser
|
||||
|
||||
|
||||
class BECWebLinksMixin:
|
||||
@staticmethod
|
||||
def open_bec_docs():
|
||||
webbrowser.open("https://beamline-experiment-control.readthedocs.io/en/latest/")
|
||||
|
||||
@staticmethod
|
||||
def open_bec_widgets_docs():
|
||||
webbrowser.open("https://bec.readthedocs.io/projects/bec-widgets/en/latest/")
|
||||
|
||||
@staticmethod
|
||||
def open_bec_bug_report():
|
||||
webbrowser.open("https://gitlab.psi.ch/groups/bec/-/issues/")
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>2104</width>
|
||||
<height>966</height>
|
||||
<width>1415</width>
|
||||
<height>832</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -17,7 +17,7 @@
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
from .motor_control_compilations import (
|
||||
MotorControlApp,
|
||||
MotorControlMap,
|
||||
MotorControlPanel,
|
||||
MotorControlPanelAbsolute,
|
||||
MotorControlPanelRelative,
|
||||
MotorCoordinateTable,
|
||||
MotorThread,
|
||||
)
|
||||
|
||||
@@ -9,5 +9,4 @@ from .crosshair import Crosshair
|
||||
from .entry_validator import EntryValidator
|
||||
from .layout_manager import GridLayoutManager
|
||||
from .rpc_decorator import register_rpc_methods, rpc_public
|
||||
from .ui_loader import UILoader
|
||||
from .validator_delegate import DoubleValidationDelegate
|
||||
|
||||
@@ -1,6 +1,31 @@
|
||||
from qtpy import QT_VERSION
|
||||
from qtpy import PYQT6, PYSIDE6, QT_VERSION
|
||||
from qtpy.QtCore import QFile, QIODevice
|
||||
|
||||
if PYSIDE6:
|
||||
from PySide6.QtUiTools import QUiLoader
|
||||
|
||||
from bec_widgets.examples.plugin_example_pyside.tictactoe import TicTacToe
|
||||
from bec_widgets.utils.plugin_utils import get_rpc_classes
|
||||
|
||||
class CustomUiLoader(QUiLoader):
|
||||
def __init__(self, baseinstance):
|
||||
super().__init__(baseinstance)
|
||||
widgets = get_rpc_classes("bec_widgets").get("top_level_classes", [])
|
||||
|
||||
# remove this line once the plugin is not needed anymore
|
||||
widgets.append(TicTacToe)
|
||||
|
||||
self.custom_widgets = {widget.__name__: widget for widget in widgets}
|
||||
|
||||
self.baseinstance = baseinstance
|
||||
|
||||
def createWidget(self, class_name, parent=None, name=""):
|
||||
if class_name in self.custom_widgets:
|
||||
widget = self.custom_widgets[class_name](parent)
|
||||
widget.setObjectName(name)
|
||||
return widget
|
||||
return super().createWidget(class_name, parent, name)
|
||||
|
||||
|
||||
class UILoader:
|
||||
"""Universal UI loader for PyQt5, PyQt6, PySide2, and PySide6."""
|
||||
@@ -14,14 +39,14 @@ class UILoader:
|
||||
self.loader = uic.loadUi
|
||||
elif QT_VERSION.startswith("6"):
|
||||
# PyQt6 or PySide6
|
||||
try:
|
||||
from PySide6.QtUiTools import QUiLoader
|
||||
|
||||
if PYSIDE6:
|
||||
self.loader = self.load_ui_pyside6
|
||||
except ImportError:
|
||||
elif PYQT6:
|
||||
from PyQt6.uic import loadUi
|
||||
|
||||
self.loader = loadUi
|
||||
else:
|
||||
raise ImportError("No compatible Qt bindings found.")
|
||||
|
||||
def load_ui_pyside6(self, ui_file, parent=None):
|
||||
"""
|
||||
@@ -33,9 +58,8 @@ class UILoader:
|
||||
Returns:
|
||||
QWidget: The loaded widget.
|
||||
"""
|
||||
from PySide6.QtUiTools import QUiLoader
|
||||
|
||||
loader = QUiLoader(parent)
|
||||
loader = CustomUiLoader(parent)
|
||||
file = QFile(ui_file)
|
||||
if not file.open(QIODevice.ReadOnly):
|
||||
raise IOError(f"Cannot open file: {ui_file}")
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"files": ["bec_status_box.py", "status_item.py",
|
||||
]
|
||||
}
|
||||
54
bec_widgets/widgets/bec_status_box/bec_status_box_plugin.py
Normal file
54
bec_widgets/widgets/bec_status_box/bec_status_box_plugin.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
from qtpy.QtDesigner import QDesignerCustomWidgetInterface
|
||||
from qtpy.QtGui import QIcon
|
||||
|
||||
from bec_widgets.widgets.bec_status_box.bec_status_box import BECStatusBox
|
||||
|
||||
DOM_XML = """
|
||||
<ui language='c++'>
|
||||
<widget class='BECStatusBox' name='bec_status_box'>
|
||||
</widget>
|
||||
</ui>
|
||||
"""
|
||||
|
||||
|
||||
class BECStatusBoxPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._form_editor = None
|
||||
|
||||
def createWidget(self, parent):
|
||||
t = BECStatusBox(parent)
|
||||
return t
|
||||
|
||||
def domXml(self):
|
||||
return DOM_XML
|
||||
|
||||
def group(self):
|
||||
return ""
|
||||
|
||||
def icon(self):
|
||||
return QIcon()
|
||||
|
||||
def includeFile(self):
|
||||
return "bec_status_box"
|
||||
|
||||
def initialize(self, form_editor):
|
||||
self._form_editor = form_editor
|
||||
|
||||
def isContainer(self):
|
||||
return False
|
||||
|
||||
def isInitialized(self):
|
||||
return self._form_editor is not None
|
||||
|
||||
def name(self):
|
||||
return "BECStatusBox"
|
||||
|
||||
def toolTip(self):
|
||||
return "BECStatusBox widget for monitoring bec services"
|
||||
|
||||
def whatsThis(self):
|
||||
return self.toolTip()
|
||||
@@ -0,0 +1,15 @@
|
||||
def main(): # pragma: no cover
|
||||
from qtpy import PYSIDE6
|
||||
|
||||
if not PYSIDE6:
|
||||
print("PYSIDE6 is not available in the environment. Cannot patch designer.")
|
||||
return
|
||||
from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
|
||||
|
||||
from bec_widgets.widgets.bec_status_box.bec_status_box_plugin import BECStatusBoxPlugin
|
||||
|
||||
QPyDesignerCustomWidgetCollection.addCustomWidget(BECStatusBoxPlugin())
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
main()
|
||||
@@ -2,16 +2,16 @@ from bec_ipython_client.main import BECIPythonClient
|
||||
from qtconsole.inprocess import QtInProcessKernelManager
|
||||
from qtconsole.manager import QtKernelManager
|
||||
from qtconsole.rich_jupyter_widget import RichJupyterWidget
|
||||
from qtpy.QtWidgets import QApplication, QMainWindow
|
||||
from qtpy.QtWidgets import QApplication
|
||||
|
||||
|
||||
class BECJupyterConsole(RichJupyterWidget): # pragma: no cover:
|
||||
def __init__(self, inprocess: bool = False):
|
||||
super().__init__()
|
||||
def __init__(self, parent=None, inprocess=True):
|
||||
super().__init__(parent=parent)
|
||||
|
||||
self.inprocess = None
|
||||
self.inprocess = inprocess
|
||||
|
||||
self.kernel_manager, self.kernel_client = self._init_kernel(inprocess=inprocess)
|
||||
self.kernel_manager, self.kernel_client = self._init_kernel(inprocess=self.inprocess)
|
||||
self.set_default_style("linux")
|
||||
self._init_bec()
|
||||
|
||||
@@ -61,12 +61,10 @@ class BECJupyterConsole(RichJupyterWidget): # pragma: no cover:
|
||||
self.kernel_manager.shutdown_kernel()
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
import sys
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
win = QMainWindow()
|
||||
win.setCentralWidget(BECJupyterConsole(True))
|
||||
win.show()
|
||||
|
||||
sys.exit(app.exec_())
|
||||
# if __name__ == "__main__": # pragma: no cover
|
||||
# import sys
|
||||
#
|
||||
# app = QApplication(sys.argv)
|
||||
# win = BECJupyterConsole(inprocess=True)
|
||||
# win.show()
|
||||
# sys.exit(app.exec_())
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"files": ["jupyter_console.py"]
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
from qtpy.QtDesigner import QDesignerCustomWidgetInterface
|
||||
from qtpy.QtGui import QIcon
|
||||
|
||||
from bec_widgets.widgets.jupyter_console.jupyter_console import BECJupyterConsole
|
||||
|
||||
DOM_XML = """
|
||||
<ui language='c++'>
|
||||
<widget class='BECJupyterConsole' name='bec_jupyter'>
|
||||
</widget>
|
||||
</ui>
|
||||
"""
|
||||
|
||||
|
||||
class BECJupyterConsolePlugin(QDesignerCustomWidgetInterface): # pragma: no cover
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._form_editor = None
|
||||
|
||||
def createWidget(self, parent):
|
||||
t = BECJupyterConsole(parent)
|
||||
return t
|
||||
|
||||
def domXml(self):
|
||||
return DOM_XML
|
||||
|
||||
def group(self):
|
||||
return ""
|
||||
|
||||
def icon(self):
|
||||
return QIcon()
|
||||
|
||||
def includeFile(self):
|
||||
return "bec_jupyter"
|
||||
|
||||
def initialize(self, form_editor):
|
||||
self._form_editor = form_editor
|
||||
|
||||
def isContainer(self):
|
||||
return False
|
||||
|
||||
def isInitialized(self):
|
||||
return self._form_editor is not None
|
||||
|
||||
def name(self):
|
||||
return "BECJupyterConsole"
|
||||
|
||||
def toolTip(self):
|
||||
return "BECJupyterConsole widget"
|
||||
|
||||
def whatsThis(self):
|
||||
return self.toolTip()
|
||||
@@ -0,0 +1,15 @@
|
||||
def main(): # pragma: no cover
|
||||
from qtpy import PYSIDE6
|
||||
|
||||
if not PYSIDE6:
|
||||
print("PYSIDE6 is not available in the environment. Cannot patch designer.")
|
||||
return
|
||||
from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
|
||||
|
||||
from bec_widgets.widgets.jupyter_console.jupyter_console_plugin import BECJupyterConsolePlugin
|
||||
|
||||
QPyDesignerCustomWidgetCollection.addCustomWidget(BECJupyterConsolePlugin())
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
main()
|
||||
@@ -16,7 +16,7 @@ from qtpy.QtWidgets import (
|
||||
QTableWidgetItem,
|
||||
)
|
||||
|
||||
from bec_widgets.utils import UILoader
|
||||
from bec_widgets.utils.ui_loader import UILoader
|
||||
from bec_widgets.widgets.motor_control.motor_control import MotorControlWidget
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from qtpy.QtCore import Signal as pyqtSignal
|
||||
from qtpy.QtCore import Slot as pyqtSlot
|
||||
from qtpy.QtWidgets import QWidget
|
||||
|
||||
from bec_widgets.utils import UILoader
|
||||
from bec_widgets.utils.ui_loader import UILoader
|
||||
from bec_widgets.widgets.motor_control.motor_control import MotorControlErrors, MotorControlWidget
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from qtpy.QtCore import Slot as pyqtSlot
|
||||
from qtpy.QtGui import QKeySequence
|
||||
from qtpy.QtWidgets import QDoubleSpinBox, QShortcut, QWidget
|
||||
|
||||
from bec_widgets.utils import UILoader
|
||||
from bec_widgets.utils.ui_loader import UILoader
|
||||
from bec_widgets.widgets.motor_control.motor_control import MotorControlWidget
|
||||
|
||||
|
||||
|
||||
15
bec_widgets/widgets/scan_control/register_scan_control.py
Normal file
15
bec_widgets/widgets/scan_control/register_scan_control.py
Normal file
@@ -0,0 +1,15 @@
|
||||
def main(): # pragma: no cover
|
||||
from qtpy import PYSIDE6
|
||||
|
||||
if not PYSIDE6:
|
||||
print("PYSIDE6 is not available in the environment. Cannot patch designer.")
|
||||
return
|
||||
from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
|
||||
|
||||
from bec_widgets.widgets.scan_control.scan_control_plugin import ScanControlPlugin
|
||||
|
||||
QPyDesignerCustomWidgetCollection.addCustomWidget(ScanControlPlugin())
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
main()
|
||||
3
bec_widgets/widgets/scan_control/scan_control.pyproject
Normal file
3
bec_widgets/widgets/scan_control/scan_control.pyproject
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"files": ["scan_control.py","scan_control_box.py"]
|
||||
}
|
||||
51
bec_widgets/widgets/scan_control/scan_control_plugin.py
Normal file
51
bec_widgets/widgets/scan_control/scan_control_plugin.py
Normal file
@@ -0,0 +1,51 @@
|
||||
from qtpy.QtDesigner import QDesignerCustomWidgetInterface
|
||||
from qtpy.QtGui import QIcon
|
||||
|
||||
from bec_widgets.widgets.scan_control import ScanControl
|
||||
|
||||
DOM_XML = """
|
||||
<ui language='c++'>
|
||||
<widget class='ScanControl' name='scan_control'>
|
||||
</widget>
|
||||
</ui>
|
||||
"""
|
||||
|
||||
|
||||
class ScanControlPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._form_editor = None
|
||||
|
||||
def createWidget(self, parent):
|
||||
t = ScanControl(parent)
|
||||
return t
|
||||
|
||||
def domXml(self):
|
||||
return DOM_XML
|
||||
|
||||
def group(self):
|
||||
return ""
|
||||
|
||||
def icon(self):
|
||||
return QIcon()
|
||||
|
||||
def includeFile(self):
|
||||
return "scan_control"
|
||||
|
||||
def initialize(self, form_editor):
|
||||
self._form_editor = form_editor
|
||||
|
||||
def isContainer(self):
|
||||
return False
|
||||
|
||||
def isInitialized(self):
|
||||
return self._form_editor is not None
|
||||
|
||||
def name(self):
|
||||
return "ScanControl"
|
||||
|
||||
def toolTip(self):
|
||||
return "ScanControl widget"
|
||||
|
||||
def whatsThis(self):
|
||||
return self.toolTip()
|
||||
15
bec_widgets/widgets/vscode/register_vscode.py
Normal file
15
bec_widgets/widgets/vscode/register_vscode.py
Normal file
@@ -0,0 +1,15 @@
|
||||
def main(): # pragma: no cover
|
||||
from qtpy import PYSIDE6
|
||||
|
||||
if not PYSIDE6:
|
||||
print("PYSIDE6 is not available in the environment. Cannot patch designer.")
|
||||
return
|
||||
from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
|
||||
|
||||
from bec_widgets.widgets.vscode.vscode_plugin import VSCodeEditorPlugin
|
||||
|
||||
QPyDesignerCustomWidgetCollection.addCustomWidget(VSCodeEditorPlugin())
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
main()
|
||||
3
bec_widgets/widgets/vscode/vscode.pyproject
Normal file
3
bec_widgets/widgets/vscode/vscode.pyproject
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"files": ["vscode.py"]
|
||||
}
|
||||
54
bec_widgets/widgets/vscode/vscode_plugin.py
Normal file
54
bec_widgets/widgets/vscode/vscode_plugin.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
from qtpy.QtDesigner import QDesignerCustomWidgetInterface
|
||||
from qtpy.QtGui import QIcon
|
||||
|
||||
from bec_widgets.widgets.vscode.vscode import VSCodeEditor
|
||||
|
||||
DOM_XML = """
|
||||
<ui language='c++'>
|
||||
<widget class='VSCodeEditor' name='vscode'>
|
||||
</widget>
|
||||
</ui>
|
||||
"""
|
||||
|
||||
|
||||
class VSCodeEditorPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._form_editor = None
|
||||
|
||||
def createWidget(self, parent):
|
||||
t = VSCodeEditor(parent)
|
||||
return t
|
||||
|
||||
def domXml(self):
|
||||
return DOM_XML
|
||||
|
||||
def group(self):
|
||||
return ""
|
||||
|
||||
def icon(self):
|
||||
return QIcon()
|
||||
|
||||
def includeFile(self):
|
||||
return "vscode"
|
||||
|
||||
def initialize(self, form_editor):
|
||||
self._form_editor = form_editor
|
||||
|
||||
def isContainer(self):
|
||||
return False
|
||||
|
||||
def isInitialized(self):
|
||||
return self._form_editor is not None
|
||||
|
||||
def name(self):
|
||||
return "VSCodeEditor"
|
||||
|
||||
def toolTip(self):
|
||||
return "VSCodeEditor widget"
|
||||
|
||||
def whatsThis(self):
|
||||
return self.toolTip()
|
||||
@@ -4,7 +4,7 @@ from unittest.mock import MagicMock, patch
|
||||
import pytest
|
||||
from bec_lib.devicemanager import DeviceContainer
|
||||
|
||||
from bec_widgets.examples import (
|
||||
from bec_widgets.examples.motor_movement.motor_control_compilations import (
|
||||
MotorControlApp,
|
||||
MotorControlMap,
|
||||
MotorControlPanel,
|
||||
|
||||
Reference in New Issue
Block a user