0
0
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:
wyzula-jan
2023-11-19 15:17:23 +01:00
parent 286e62df92
commit ee3b616ec1
4 changed files with 67 additions and 165 deletions

View File

@ -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

View File

@ -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()

View File

@ -1 +1 @@
from .toolbar import ModularToolbar
from .toolbar import ModularToolBar

View File

@ -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")
for widget_type, actions in self.handler.items():
if isinstance(child, widget_type):
self.populate_toolbar(child, actions)
return
def set_widget(self, widget):
self.clear_buttons()
self.add_buttons([OpenFileButton(), SaveFileButton(), RunScriptButton()])
self.connectToWidget(widget)
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 update_buttons(self):
if self.current_widget is None:
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 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)