mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-14 11:41:49 +02:00
refactor: toolbar.py migration to native qt QToolBar
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
from .monitor import BECMonitor, ConfigDialog
|
||||
from .scan_control import ScanControl
|
||||
from .toolbar import ModularToolbar
|
||||
from .toolbar import ModularToolBar
|
||||
from .editor import BECEditor
|
||||
|
@ -1,25 +1,17 @@
|
||||
import subprocess
|
||||
|
||||
import qdarktheme
|
||||
from qtpy.Qsci import QsciScintilla, QsciLexerPython
|
||||
from qtpy.QtCore import QFile, QTextStream, Signal, QThread
|
||||
from qtpy.QtGui import QColor, QFont, QAction, QShortcut, QKeySequence
|
||||
from qtpy.QtGui import QColor, QFont
|
||||
from qtpy.QtWidgets import (
|
||||
QApplication,
|
||||
QMainWindow,
|
||||
QFileDialog,
|
||||
QPushButton,
|
||||
QTextEdit,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
)
|
||||
|
||||
# from PyQt6.Qsci import QsciScintilla, QsciLexerPython
|
||||
from qtpy.Qsci import QsciScintilla, QsciLexerPython
|
||||
|
||||
# from bec_widgets.widgets.toolbar.toolbar import ModularToolbar
|
||||
|
||||
# from bec_widgets.widgets import ModularToolbar
|
||||
|
||||
|
||||
class ScriptRunnerThread(QThread):
|
||||
outputSignal = Signal(str)
|
||||
@ -57,20 +49,15 @@ class BECEditor(QWidget):
|
||||
self.editor = QsciScintilla()
|
||||
self.terminal = QTextEdit()
|
||||
self.terminal.setReadOnly(True)
|
||||
# self.runButton = QPushButton("Run Script")
|
||||
|
||||
# Layout
|
||||
layout = QVBoxLayout()
|
||||
layout.addWidget(self.editor)
|
||||
# layout.addWidget(self.runButton)
|
||||
layout.addWidget(self.terminal)
|
||||
self.setLayout(layout)
|
||||
self.layout = QVBoxLayout()
|
||||
self.layout.addWidget(self.editor)
|
||||
self.layout.addWidget(self.terminal)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
self.setupEditor()
|
||||
|
||||
# Connect the run button
|
||||
# self.runButton.clicked.connect(self.runScript)
|
||||
|
||||
def setupEditor(self):
|
||||
# Set the lexer for Python
|
||||
self.lexer = QsciLexerPython()
|
||||
@ -89,8 +76,6 @@ class BECEditor(QWidget):
|
||||
|
||||
# Additional UI elements like menu for load/save can be added here
|
||||
self.setEditorStyle()
|
||||
self.createActions()
|
||||
self.createMenus()
|
||||
|
||||
def setEditorStyle(self):
|
||||
# Dracula Theme Colors
|
||||
@ -137,23 +122,6 @@ class BECEditor(QWidget):
|
||||
def updateTerminal(self, text):
|
||||
self.terminal.append(text)
|
||||
|
||||
def createMenus(self):
|
||||
...
|
||||
# self.fileMenu = self.menuBar().addMenu("&File")
|
||||
# self.fileMenu.addAction(self.openAct)
|
||||
# self.fileMenu.addAction(self.saveAct)
|
||||
|
||||
def createActions(self):
|
||||
self.openAct = QAction("&Open...", self, triggered=self.openFile)
|
||||
self.saveAct = QAction("&Save", self, triggered=self.saveFile)
|
||||
|
||||
# Shortcuts
|
||||
self.openShortcut = QShortcut(QKeySequence("Ctrl+O"), self)
|
||||
self.openShortcut.activated.connect(self.openFile)
|
||||
|
||||
self.saveShortcut = QShortcut(QKeySequence("Ctrl+S"), self)
|
||||
self.saveShortcut.activated.connect(self.saveFile)
|
||||
|
||||
def openFile(self):
|
||||
path, _ = QFileDialog.getOpenFileName(self, "Open file", "", "Python files (*.py)")
|
||||
if path:
|
||||
@ -174,28 +142,16 @@ class BECEditor(QWidget):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from bec_widgets.widgets.toolbar.toolbar import ModularToolbar
|
||||
from bec_widgets.widgets.toolbar.toolbar import ModularToolBar
|
||||
|
||||
# app = QApplication([])
|
||||
# qdarktheme.setup_theme("auto")
|
||||
# mainWin = BECEditor()
|
||||
# mainWin.show()
|
||||
# app.exec()
|
||||
app = QApplication([])
|
||||
qdarktheme.setup_theme("auto")
|
||||
window = QWidget()
|
||||
layout = QVBoxLayout(window)
|
||||
|
||||
editor = BECEditor()
|
||||
# toolbar_auto = ModularToolbar()
|
||||
mainWin = BECEditor()
|
||||
|
||||
# Manual initialization
|
||||
toolbar_manual = ModularToolbar(auto_init=False)
|
||||
toolbar_manual.set_target_widget(editor)
|
||||
toolbar_manual = ModularToolBar()
|
||||
toolbar_manual.set_target_widget(mainWin)
|
||||
|
||||
layout.addWidget(toolbar_manual)
|
||||
layout.addWidget(editor)
|
||||
|
||||
window.setLayout(layout)
|
||||
window.show()
|
||||
mainWin.layout.insertWidget(0, toolbar_manual)
|
||||
mainWin.show()
|
||||
app.exec()
|
||||
|
@ -1 +1 @@
|
||||
from .toolbar import ModularToolbar
|
||||
from .toolbar import ModularToolBar
|
||||
|
@ -1,127 +1,73 @@
|
||||
from PyQt6.QtCore import QTimer
|
||||
from PyQt6.QtWidgets import QPushButton
|
||||
from PyQt6.QtWidgets import QToolBar
|
||||
from qtpy.QtCore import QTimer
|
||||
from qtpy.QtGui import QAction
|
||||
from qtpy.QtWidgets import QPushButton
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from PyQt6.QtWidgets import QHBoxLayout, QWidget
|
||||
from qtpy.QtWidgets import QHBoxLayout, QWidget
|
||||
|
||||
from bec_widgets.widgets.editor.editor import BECEditor
|
||||
|
||||
|
||||
class AbstractToolbarButton(QPushButton): # , ABC): #TODO decide if ABC useful for this case..
|
||||
def __init__(self, text, slot_name, parent=None):
|
||||
super().__init__(text, parent)
|
||||
self.slot_name = slot_name
|
||||
|
||||
# @abstractmethod
|
||||
def setup_button(self):
|
||||
"""
|
||||
Setup specific properties for the button.
|
||||
"""
|
||||
class ToolBarAction(ABC):
|
||||
@abstractmethod
|
||||
def create(self, target: QWidget):
|
||||
pass
|
||||
|
||||
def connect_to_widget(self, widget):
|
||||
slot_function = getattr(widget, self.slot_name, None)
|
||||
if slot_function and callable(slot_function):
|
||||
self.clicked.connect(slot_function)
|
||||
|
||||
class OpenFileAction: # (ToolBarAction):
|
||||
def create(self, target: QWidget):
|
||||
action = QAction("Open File", target)
|
||||
action.triggered.connect(target.openFile)
|
||||
return action
|
||||
|
||||
|
||||
class OpenFileButton(AbstractToolbarButton):
|
||||
class SaveFileAction:
|
||||
def create(self, target):
|
||||
action = QAction("Save File", target)
|
||||
action.triggered.connect(target.saveFile)
|
||||
return action
|
||||
|
||||
|
||||
class RunScriptAction:
|
||||
def create(self, target):
|
||||
action = QAction("Run Script", target)
|
||||
action.triggered.connect(target.runScript)
|
||||
return action
|
||||
|
||||
|
||||
class ModularToolBar(QToolBar):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__("Open File", "openFile", parent)
|
||||
self.setup_button()
|
||||
|
||||
def setup_button(self):
|
||||
self.setText("Open File")
|
||||
# Add specific setup for Open File Button
|
||||
# pass
|
||||
|
||||
|
||||
class SaveFileButton(AbstractToolbarButton):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__("Save File", "saveFile", parent)
|
||||
self.setup_button()
|
||||
|
||||
def setup_button(self):
|
||||
self.setText("Save File")
|
||||
# Add specific setup for Save File Button
|
||||
# pass
|
||||
|
||||
|
||||
class RunScriptButton(AbstractToolbarButton):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__("Run Script", "runScript", parent)
|
||||
self.setup_button()
|
||||
|
||||
def setup_button(self):
|
||||
# Add specific setup for Run Script Button
|
||||
self.setText("Run Script")
|
||||
# pass
|
||||
|
||||
|
||||
class ModularToolbar(QWidget):
|
||||
def __init__(self, parent=None, auto_init=False):
|
||||
super().__init__(parent)
|
||||
# self.layout = QHBoxLayout()
|
||||
# self.setLayout(self.layout)
|
||||
# self.initialized = False
|
||||
self.layout = QHBoxLayout()
|
||||
self.setLayout(self.layout)
|
||||
self.current_widget = None
|
||||
self.auto_init = auto_init
|
||||
self.initialized = False
|
||||
if self.auto_init:
|
||||
QTimer.singleShot(0, self.detect_context_and_update_buttons)
|
||||
|
||||
def set_target_widget(self, widget):
|
||||
self.current_widget = widget
|
||||
self.update_buttons()
|
||||
|
||||
def showEvent(self, event):
|
||||
super().showEvent(event)
|
||||
if not self.initialized:
|
||||
self.detect_context_and_update_buttons()
|
||||
self.initialized = True
|
||||
|
||||
def detect_context_and_update_buttons(self):
|
||||
if not self.auto_init or self.initialized:
|
||||
return
|
||||
self.handler = {
|
||||
BECEditor: [OpenFileAction(), SaveFileAction(), RunScriptAction()],
|
||||
# BECMonitor: [SomeOtherAction(), AnotherAction()], # Example for another widget
|
||||
} # TODO also buggy fox later
|
||||
QTimer.singleShot(0, self.detect_context_and_update_actions) # TODO buggy disabled for now
|
||||
self.setStyleSheet("QToolBar { background: transparent; }")
|
||||
|
||||
def detect_context_and_update_actions(self): # TODO buggy disabled for now
|
||||
parent_widget = self.parent()
|
||||
if parent_widget is None:
|
||||
return
|
||||
|
||||
for child in parent_widget.children():
|
||||
if isinstance(child, BECEditor):
|
||||
self.set_widget(child)
|
||||
print("BECEditor init success!")
|
||||
break
|
||||
else:
|
||||
print("no supported widget detected")
|
||||
|
||||
def set_widget(self, widget):
|
||||
self.clear_buttons()
|
||||
self.add_buttons([OpenFileButton(), SaveFileButton(), RunScriptButton()])
|
||||
self.connectToWidget(widget)
|
||||
|
||||
def update_buttons(self):
|
||||
if self.current_widget is None:
|
||||
for widget_type, actions in self.handler.items():
|
||||
if isinstance(child, widget_type):
|
||||
self.populate_toolbar(child, actions)
|
||||
return
|
||||
|
||||
self.clear_buttons()
|
||||
# if isinstance(self.current_widget, BECEditor):
|
||||
self.add_buttons([OpenFileButton(), SaveFileButton(), RunScriptButton()])
|
||||
# Additional conditions for other widget types can be added here
|
||||
def set_target_widget(self, widget):
|
||||
self.populate_toolbar(
|
||||
widget, actions=[OpenFileAction(), SaveFileAction(), RunScriptAction()]
|
||||
)
|
||||
# for widget_type, actions in self.handler.items(): #TODO for automatic population
|
||||
# if isinstance(widget, widget_type):
|
||||
# self.populate_toolbar(widget, actions)
|
||||
# break
|
||||
|
||||
def clear_buttons(self):
|
||||
for button in self.findChildren(AbstractToolbarButton):
|
||||
self.layout.removeWidget(button)
|
||||
button.deleteLater()
|
||||
|
||||
def add_buttons(self, buttons):
|
||||
for button in buttons:
|
||||
self.layout.addWidget(button)
|
||||
button.connect_to_widget(self.current_widget)
|
||||
|
||||
def connectToWidget(self, target_widget):
|
||||
for button in self.findChildren(AbstractToolbarButton):
|
||||
button.connect_to_widget(target_widget)
|
||||
def populate_toolbar(self, target_widget, actions):
|
||||
self.clear()
|
||||
for action_creator in actions:
|
||||
action = action_creator.create(target_widget)
|
||||
self.addAction(action)
|
||||
|
Reference in New Issue
Block a user