0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 11:41:49 +02:00

feat: basic text editor + running terminal output

This commit is contained in:
wyzula-jan
2023-11-16 14:06:06 +01:00
parent 745aa6e812
commit 94878448c8

View File

@ -0,0 +1,184 @@
import sys
import subprocess
import threading
import qdarktheme
from PyQt6.QtCore import QFile, QTextStream, pyqtSignal
from PyQt6.QtGui import QColor, QFont, QAction
from PyQt6.QtWidgets import (
QApplication,
QMainWindow,
QFileDialog,
QPushButton,
QTextEdit,
QVBoxLayout,
QWidget,
)
from PyQt6.Qsci import QsciScintilla, QsciLexerPython
class PythonEditor(QMainWindow):
# outputSignal = pyqtSignal(str)
def __init__(self):
super().__init__()
# Initialize the editor and terminal
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)
# Container widget
container = QWidget()
container.setLayout(layout)
self.setCentralWidget(container)
self.setupEditor()
# Connect the run button
self.runButton.clicked.connect(self.runScript)
# self.outputSignal.connect(self.updateTerminal)
def setupEditor(self):
# Set the lexer for Python
self.lexer = QsciLexerPython()
self.editor.setLexer(self.lexer)
# Enable features
self.editor.setAutoIndent(True)
self.editor.setIndentationsUseTabs(False)
self.editor.setIndentationWidth(4)
self.editor.setAutoCompletionSource(QsciScintilla.AutoCompletionSource.AcsAll)
self.editor.setAutoCompletionThreshold(1)
# Enable line numbers in the margin
self.editor.setMarginType(0, QsciScintilla.MarginType.NumberMargin)
self.editor.setMarginWidth(0, "0000") # Adjust the width as needed
# Additional UI elements like menu for load/save can be added here
self.setEditorStyle()
self.createActions()
self.createMenus()
def setEditorStyle(self):
# Dracula Theme Colors
backgroundColor = QColor("#282a36")
textColor = QColor("#f8f8f2")
keywordColor = QColor("#8be9fd")
stringColor = QColor("#f1fa8c")
commentColor = QColor("#6272a4")
classFunctionColor = QColor("#50fa7b")
# Set Font
font = QFont()
font.setFamily("Consolas")
font.setPointSize(10)
self.editor.setFont(font)
self.editor.setMarginsFont(font)
# Set Editor Colors
self.editor.setMarginsBackgroundColor(backgroundColor)
self.editor.setMarginsForegroundColor(textColor)
self.editor.setCaretForegroundColor(textColor)
self.editor.setCaretLineBackgroundColor(QColor("#44475a"))
self.editor.setPaper(backgroundColor)
self.editor.setColor(textColor)
# Syntax Highlighting Colors
lexer = self.editor.lexer()
if lexer:
lexer.setDefaultPaper(backgroundColor)
lexer.setDefaultColor(textColor)
lexer.setColor(keywordColor, QsciLexerPython.Keyword)
lexer.setColor(stringColor, QsciLexerPython.DoubleQuotedString)
lexer.setColor(stringColor, QsciLexerPython.SingleQuotedString)
lexer.setColor(commentColor, QsciLexerPython.Comment)
lexer.setColor(classFunctionColor, QsciLexerPython.ClassName)
lexer.setColor(classFunctionColor, QsciLexerPython.FunctionMethodName)
def runScript(self):
# Use threading to run the script
# thread = threading.Thread(target=self.executeScript)
# thread.start()
# Save the current script to a temporary file or use the existing file
script = self.editor.text()
with open("temp_script.py", "w") as file:
file.write(script)
# Run the script and capture output
process = subprocess.Popen(
["python", "temp_script.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
)
output, error = process.communicate()
# Display output and error in the terminal
self.terminal.clear()
if output:
self.terminal.append(output)
if error:
self.terminal.append(error)
# def executeScript(self):
# # Save the current script to a temporary file or use the existing file
# script = self.editor.text()
# with open("temp_script.py", "w") as file:
# file.write(script)
#
# # Run the script and capture output
# process = subprocess.Popen(
# ["python", "temp_script.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
# )
# output, error = process.communicate()
#
# # Emit the signal with the output
# if output:
# self.outputSignal.emit(output)
# if error:
# self.outputSignal.emit(error)
#
# def updateTerminal(self, text):
# # Update the terminal with output
# 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, shortcut="Ctrl+O", triggered=self.openFile)
self.saveAct = QAction("&Save", self, shortcut="Ctrl+S", triggered=self.saveFile)
def openFile(self):
path, _ = QFileDialog.getOpenFileName(self, "Open file", "", "Python files (*.py)")
if path:
file = QFile(path)
if file.open(QFile.OpenModeFlag.ReadOnly | QFile.OpenModeFlag.Text):
text = QTextStream(file).readAll()
self.editor.setText(text)
file.close()
def saveFile(self):
path, _ = QFileDialog.getSaveFileName(self, "Save file", "", "Python files (*.py)")
if path:
file = QFile(path)
if file.open(QFile.OpenModeFlag.WriteOnly | QFile.OpenModeFlag.Text):
text = self.editor.text()
QTextStream(file) << text
file.close()
if __name__ == "__main__":
app = QApplication([])
qdarktheme.setup_theme()
mainWin = PythonEditor()
mainWin.show()
app.exec()