diff options
author | Rahul P | 2023-06-11 16:46:32 +0530 |
---|---|---|
committer | GitHub | 2023-06-11 16:46:32 +0530 |
commit | 9a5f3dabc357277b384c51ccf047f5580772f454 (patch) | |
tree | afc4cf7c8d461576f03393445f3741eecfa650ee /src/frontEnd | |
parent | b145afdb869564df4131f0b0b472116ca744ef65 (diff) | |
parent | 4eea06f6fcd654c7f0919f395ff42fabbafa0171 (diff) | |
download | eSim-9a5f3dabc357277b384c51ccf047f5580772f454.tar.gz eSim-9a5f3dabc357277b384c51ccf047f5580772f454.tar.bz2 eSim-9a5f3dabc357277b384c51ccf047f5580772f454.zip |
Merge pull request #243 from pranavkaruvally/master
Send Ngspice simulation to background
Diffstat (limited to 'src/frontEnd')
-rw-r--r-- | src/frontEnd/Application.py | 145 | ||||
-rwxr-xr-x | src/frontEnd/DockArea.py | 188 | ||||
-rw-r--r-- | src/frontEnd/TerminalUi.py | 143 | ||||
-rw-r--r-- | src/frontEnd/TerminalUi.ui | 163 |
4 files changed, 465 insertions, 174 deletions
diff --git a/src/frontEnd/Application.py b/src/frontEnd/Application.py index 7588b1a1..790bf779 100644 --- a/src/frontEnd/Application.py +++ b/src/frontEnd/Application.py @@ -10,14 +10,17 @@ # BUGS: --- # NOTES: --- # AUTHOR: Fahim Khan, fahim.elex@gmail.com -# MAINTAINED: Rahul Paknikar, rahulp@cse.iitb.ac.in +# MAINTAINED: Rahul Paknikar, rahulp@iitb.ac.in # Sumanto Kar, sumantokar@iitb.ac.in +# Pranav P, pranavsdreams@gmail.com # ORGANIZATION: eSim Team at FOSSEE, IIT Bombay # CREATED: Tuesday 24 February 2015 -# REVISION: Tuesday 13 September 2022 +# REVISION: Wednesday 07 June 2023 # ========================================================================= import os +import sys +import shutil import traceback if os.name == 'nt': @@ -28,20 +31,16 @@ else: init_path = '../../' from PyQt5 import QtGui, QtCore, QtWidgets +from PyQt5.Qt import QSize from configuration.Appconfig import Appconfig +from frontEnd import ProjectExplorer +from frontEnd import Workspace +from frontEnd import DockArea from projManagement.openProject import OpenProjectInfo from projManagement.newProject import NewProjectInfo from projManagement.Kicad import Kicad from projManagement.Validation import Validation from projManagement import Worker -from frontEnd import ProjectExplorer -from frontEnd import Workspace -from frontEnd import DockArea -from PyQt5.Qt import QSize -import shutil -import time -import sys -import psutil # Its our main window of application. @@ -49,6 +48,7 @@ import psutil class Application(QtWidgets.QMainWindow): """This class initializes all objects used in this file.""" global project_name + simulationEndSignal = QtCore.pyqtSignal(QtCore.QProcess.ExitStatus, int) def __init__(self, *args): """Initialize main Application window.""" @@ -59,6 +59,9 @@ class Application(QtWidgets.QMainWindow): # Flag for mode of operation. Default is set to offline mode. self.online_flag = False + # Set slot for simulation end signal to plot simulation data + self.simulationEndSignal.connect(self.plotSimulationData) + # Creating require Object self.obj_workspace = Workspace.Workspace() self.obj_Mainview = MainView() @@ -534,109 +537,59 @@ class Application(QtWidgets.QMainWindow): print("Current Project is : ", self.obj_appconfig.current_project) self.obj_Mainview.obj_dockarea.usermanual() - def checkIfProcessRunning(self, processName): - ''' - Check if there is any running process - that contains the given name processName. - ''' - # Iterate over the all the running process - for proc in psutil.process_iter(): + @QtCore.pyqtSlot(QtCore.QProcess.ExitStatus, int) + def plotSimulationData(self, exitCode, exitStatus): + """Enables interaction for new simulation and + displays the plotter dock where graphs can be plotted. + """ + self.ngspice.setEnabled(True) + self.conversion.setEnabled(True) + self.closeproj.setEnabled(True) + self.wrkspce.setEnabled(True) + + if exitStatus == QtCore.QProcess.NormalExit and exitCode == 0: try: - # Check if process name contains the given name string. - if processName.lower() in proc.name().lower(): - return True - except (psutil.NoSuchProcess, - psutil.AccessDenied, psutil.ZombieProcess): - pass - return False + self.obj_Mainview.obj_dockarea.plottingEditor() + except Exception as e: + self.msg = QtWidgets.QErrorMessage() + self.msg.setModal(True) + self.msg.setWindowTitle("Error Message") + self.msg.showMessage( + 'Data could not be plotted. Please try again.' + ) + self.msg.exec_() + print("Exception Message:", str(e), traceback.format_exc()) + self.obj_appconfig.print_error('Exception Message : ' + + str(e)) def open_ngspice(self): """This Function execute ngspice on current project.""" - self.projDir = self.obj_appconfig.current_project["ProjectName"] + projDir = self.obj_appconfig.current_project["ProjectName"] - if self.projDir is not None: + if projDir is not None: + projName = os.path.basename(projDir) + ngspiceNetlist = os.path.join(projDir, projName + ".cir.out") - # Edited by Sumanto Kar 25/08/2021 - if self.obj_Mainview.obj_dockarea.ngspiceEditor( - self.projDir) is False: + if not os.path.isfile(ngspiceNetlist): print( "Netlist file (*.cir.out) not found." ) - self.msg = QtWidgets.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Error Message") self.msg.showMessage( - 'Netlist file (*.cir.out) not found.' + 'Netlist (*.cir.out) not found.' ) self.msg.exec_() return - currTime = time.time() - count = 0 - while True: - try: - # if os.name == 'nt': - # proc = 'mintty' - # else: - # proc = 'xterm' - - # Edited by Sumanto Kar 25/08/2021 - if os.name != 'nt' and \ - self.checkIfProcessRunning('xterm') is False: - self.msg = QtWidgets.QErrorMessage() - self.msg.setModal(True) - self.msg.setWindowTitle("Warning Message") - self.msg.showMessage( - 'Simulation was interrupted/failed. ' - 'Please close all the Ngspice windows ' - 'and then rerun the simulation.' - ) - self.msg.exec_() - return + self.obj_Mainview.obj_dockarea.ngspiceEditor( + projName, ngspiceNetlist, self.simulationEndSignal) - st = os.stat(os.path.join(self.projDir, "plot_data_i.txt")) - if st.st_mtime >= currTime: - break - except Exception: - pass - time.sleep(1) - - # Fail Safe ===> - count += 1 - if count >= 10: - print( - "Ngspice taking too long for simulation. " - "Check netlist file (*.cir.out) " - "to change simulation parameters." - ) - - self.msg = QtWidgets.QErrorMessage() - self.msg.setModal(True) - self.msg.setWindowTitle("Warning Message") - self.msg.showMessage( - 'Ngspice taking too long for simulation. ' - 'Check netlist file (*.cir.out) ' - 'to change simulation parameters.' - ) - self.msg.exec_() - - return - - # Calling Python Plotting - try: - self.obj_Mainview.obj_dockarea.plottingEditor() - except Exception as e: - self.msg = QtWidgets.QErrorMessage() - self.msg.setModal(True) - self.msg.setWindowTitle("Error Message") - self.msg.showMessage( - 'Error while opening python plotting Editor.' - ' Please look at console for more details.' - ) - self.msg.exec_() - print("Exception Message:", str(e), traceback.format_exc()) - self.obj_appconfig.print_error('Exception Message : ' + str(e)) + self.ngspice.setEnabled(False) + self.conversion.setEnabled(False) + self.closeproj.setEnabled(False) + self.wrkspce.setEnabled(False) else: self.msg = QtWidgets.QErrorMessage() @@ -739,7 +692,7 @@ class Application(QtWidgets.QMainWindow): # Creating a command for Ngspice to Modelica converter self.cmd1 = " python3 ../ngspicetoModelica/NgspicetoModelica.py "\ - +self.ngspiceNetlist + + self.ngspiceNetlist self.obj_workThread1 = Worker.WorkerThread(self.cmd1) self.obj_workThread1.start() if self.obj_validation.validateTool("OMEdit"): diff --git a/src/frontEnd/DockArea.py b/src/frontEnd/DockArea.py index 461240b9..7037dcfd 100755 --- a/src/frontEnd/DockArea.py +++ b/src/frontEnd/DockArea.py @@ -89,6 +89,7 @@ class DockArea(QtWidgets.QMainWindow): """This function create widget for interactive PythonPlotting.""" self.projDir = self.obj_appconfig.current_project["ProjectName"] self.projName = os.path.basename(self.projDir) + dockName = f'Plotting-{self.projName}-' # self.project = os.path.join(self.projDir, self.projName) global count @@ -99,66 +100,65 @@ class DockArea(QtWidgets.QMainWindow): # Adding to main Layout self.plottingWidget.setLayout(self.plottingLayout) - dock['Plotting-' + str(count) - ] = QtWidgets.QDockWidget('Plotting-' + str(count)) - dock['Plotting-' + str(count)].setWidget(self.plottingWidget) + dock[dockName + str(count) + ] = QtWidgets.QDockWidget(dockName + + str(count)) + dock[dockName + str(count)] \ + .setWidget(self.plottingWidget) self.addDockWidget(QtCore.Qt.TopDockWidgetArea, - dock['Plotting-' + str(count)]) - self.tabifyDockWidget(dock['Welcome'], dock['Plotting-' + str(count)]) + dock[dockName + str(count)]) + self.tabifyDockWidget(dock['Welcome'], + dock[dockName + str(count)]) - dock['Plotting-' + str(count)].setVisible(True) - dock['Plotting-' + str(count)].setFocus() - dock['Plotting-' + str(count)].raise_() + dock[dockName + str(count)].setVisible(True) + dock[dockName + str(count)].setFocus() + dock[dockName + str(count)].raise_() temp = self.obj_appconfig.current_project['ProjectName'] if temp: self.obj_appconfig.dock_dict[temp].append( - dock['Plotting-' + str(count)] + dock[dockName + str(count)] ) count = count + 1 - def ngspiceEditor(self, projDir): + def ngspiceEditor(self, projName, netlist, simEndSignal): """ This function creates widget for Ngspice window.""" - self.projDir = projDir - self.projName = os.path.basename(self.projDir) - self.ngspiceNetlist = os.path.join( - self.projDir, self.projName + ".cir.out") - - # Edited by Sumanto Kar 25/08/2021 - if os.path.isfile(self.ngspiceNetlist) is False: - return False - global count self.ngspiceWidget = QtWidgets.QWidget() self.ngspiceLayout = QtWidgets.QVBoxLayout() self.ngspiceLayout.addWidget( - NgspiceWidget(self.ngspiceNetlist, self.projDir) + NgspiceWidget(netlist, simEndSignal) ) # Adding to main Layout self.ngspiceWidget.setLayout(self.ngspiceLayout) - dock['NgSpice-' + str(count) - ] = QtWidgets.QDockWidget('NgSpice-' + str(count)) - dock['NgSpice-' + str(count)].setWidget(self.ngspiceWidget) + dockName = f'Simulation-{projName}-' + dock[dockName + str(count) + ] = QtWidgets.QDockWidget(dockName + + str(count)) + dock[dockName + str(count)] \ + .setWidget(self.ngspiceWidget) self.addDockWidget(QtCore.Qt.TopDockWidgetArea, - dock['NgSpice-' + str(count)]) - self.tabifyDockWidget(dock['Welcome'], dock['NgSpice-' + str(count)]) + dock[dockName + str(count)]) + self.tabifyDockWidget(dock['Welcome'], + dock[dockName + + str(count)]) # CSS - dock['NgSpice-' + str(count)].setStyleSheet(" \ + dock[dockName + str(count)].setStyleSheet(" \ .QWidget { border-radius: 15px; border: 1px solid gray; padding: 0px;\ width: 200px; height: 150px; } \ ") - dock['NgSpice-' + str(count)].setVisible(True) - dock['NgSpice-' + str(count)].setFocus() - dock['NgSpice-' + str(count)].raise_() + dock[dockName + str(count)].setVisible(True) + dock[dockName + str(count)].setFocus() + dock[dockName + str(count)].raise_() temp = self.obj_appconfig.current_project['ProjectName'] if temp: self.obj_appconfig.dock_dict[temp].append( - dock['NgSpice-' + str(count)] + dock[dockName + str(count)] ) count = count + 1 @@ -166,6 +166,11 @@ class DockArea(QtWidgets.QMainWindow): """This function defines UI for model editor.""" print("in model editor") global count + + projDir = self.obj_appconfig.current_project["ProjectName"] + projName = os.path.basename(projDir) + dockName = f'Model Editor-{projName}-' + self.modelwidget = QtWidgets.QWidget() self.modellayout = QtWidgets.QVBoxLayout() @@ -174,23 +179,25 @@ class DockArea(QtWidgets.QMainWindow): # Adding to main Layout self.modelwidget.setLayout(self.modellayout) - dock['Model Editor-' + - str(count)] = QtWidgets.QDockWidget('Model Editor-' + str(count)) - dock['Model Editor-' + str(count)].setWidget(self.modelwidget) + dock[dockName + + str(count)] = QtWidgets.QDockWidget(dockName + + str(count)) + dock[dockName + str(count)] \ + .setWidget(self.modelwidget) self.addDockWidget(QtCore.Qt.TopDockWidgetArea, - dock['Model Editor-' + str(count)]) + dock[dockName + str(count)]) self.tabifyDockWidget(dock['Welcome'], - dock['Model Editor-' + str(count)]) + dock[dockName + str(count)]) # CSS - dock['Model Editor-' + str(count)].setStyleSheet(" \ + dock[dockName + str(count)].setStyleSheet(" \ .QWidget { border-radius: 15px; border: 1px solid gray; \ padding: 5px; width: 200px; height: 150px; } \ ") - dock['Model Editor-' + str(count)].setVisible(True) - dock['Model Editor-' + str(count)].setFocus() - dock['Model Editor-' + str(count)].raise_() + dock[dockName + str(count)].setVisible(True) + dock[dockName + str(count)].setFocus() + dock[dockName + str(count)].raise_() count = count + 1 @@ -199,91 +206,109 @@ class DockArea(QtWidgets.QMainWindow): This function is creating Editor UI for Kicad to Ngspice conversion. """ global count + + projDir = self.obj_appconfig.current_project["ProjectName"] + projName = os.path.basename(projDir) + dockName = f'Netlist-{projName}-' + self.kicadToNgspiceWidget = QtWidgets.QWidget() self.kicadToNgspiceLayout = QtWidgets.QVBoxLayout() self.kicadToNgspiceLayout.addWidget(MainWindow(clarg1, clarg2)) self.kicadToNgspiceWidget.setLayout(self.kicadToNgspiceLayout) - dock['kicadToNgspice-' + str(count)] = \ - QtWidgets.QDockWidget('kicadToNgspice-' + str(count)) - dock['kicadToNgspice-' + + dock[dockName + str(count)] = \ + QtWidgets.QDockWidget(dockName + str(count)) + dock[dockName + str(count)].setWidget(self.kicadToNgspiceWidget) self.addDockWidget(QtCore.Qt.TopDockWidgetArea, - dock['kicadToNgspice-' + str(count)]) + dock[dockName + str(count)]) self.tabifyDockWidget(dock['Welcome'], - dock['kicadToNgspice-' + str(count)]) + dock[dockName + str(count)]) # CSS - dock['kicadToNgspice-' + str(count)].setStyleSheet(" \ + dock[dockName + str(count)].setStyleSheet(" \ .QWidget { border-radius: 15px; border: 1px solid gray;\ padding: 5px; width: 200px; height: 150px; } \ ") - dock['kicadToNgspice-' + str(count)].setVisible(True) - dock['kicadToNgspice-' + str(count)].setFocus() - dock['kicadToNgspice-' + str(count)].raise_() - dock['kicadToNgspice-' + str(count)].activateWindow() + dock[dockName + str(count)].setVisible(True) + dock[dockName + str(count)].setFocus() + dock[dockName + str(count)].raise_() + dock[dockName + str(count)].activateWindow() temp = self.obj_appconfig.current_project['ProjectName'] if temp: self.obj_appconfig.dock_dict[temp].append( - dock['kicadToNgspice-' + str(count)] + dock[dockName + str(count)] ) count = count + 1 def subcircuiteditor(self): """This function creates a widget for different subcircuit options.""" global count + + projDir = self.obj_appconfig.current_project["ProjectName"] + projName = os.path.basename(projDir) + dockName = f'Subcircuit-{projName}-' + self.subcktWidget = QtWidgets.QWidget() self.subcktLayout = QtWidgets.QVBoxLayout() self.subcktLayout.addWidget(Subcircuit(self)) self.subcktWidget.setLayout(self.subcktLayout) - dock['Subcircuit-' + - str(count)] = QtWidgets.QDockWidget('Subcircuit-' + str(count)) - dock['Subcircuit-' + str(count)].setWidget(self.subcktWidget) + dock[dockName + + str(count)] = QtWidgets.QDockWidget(dockName + + str(count)) + dock[dockName + str(count)] \ + .setWidget(self.subcktWidget) self.addDockWidget(QtCore.Qt.TopDockWidgetArea, - dock['Subcircuit-' + str(count)]) + dock[dockName + str(count)]) self.tabifyDockWidget(dock['Welcome'], - dock['Subcircuit-' + str(count)]) + dock[dockName + str(count)]) # CSS - dock['Subcircuit-' + str(count)].setStyleSheet(" \ + dock[dockName + str(count)].setStyleSheet(" \ .QWidget { border-radius: 15px; border: 1px solid gray;\ padding: 5px; width: 200px; height: 150px; } \ ") - dock['Subcircuit-' + str(count)].setVisible(True) - dock['Subcircuit-' + str(count)].setFocus() - dock['Subcircuit-' + str(count)].raise_() + dock[dockName + str(count)].setVisible(True) + dock[dockName + str(count)].setFocus() + dock[dockName + str(count)].raise_() count = count + 1 def makerchip(self): """This function creates a widget for different subcircuit options.""" global count + + projDir = self.obj_appconfig.current_project["ProjectName"] + projName = os.path.basename(projDir) + dockName = f'Makerchip-{projName}-' + self.makerWidget = QtWidgets.QWidget() self.makerLayout = QtWidgets.QVBoxLayout() self.makerLayout.addWidget(makerchip(self)) self.makerWidget.setLayout(self.makerLayout) - dock['Makerchip-' + - str(count)] = QtWidgets.QDockWidget('Makerchip-' + str(count)) - dock['Makerchip-' + str(count)].setWidget(self.makerWidget) + dock[dockName + + str(count)] = QtWidgets.QDockWidget(dockName + + str(count)) + dock[dockName + str(count)].setWidget(self.makerWidget) self.addDockWidget(QtCore.Qt.TopDockWidgetArea, - dock['Makerchip-' + str(count)]) + dock[dockName + str(count)]) self.tabifyDockWidget(dock['Welcome'], - dock['Makerchip-' + str(count)]) + dock[dockName + str(count)]) # CSS - dock['Makerchip-' + str(count)].setStyleSheet(" \ + dock[dockName + str(count)].setStyleSheet(" \ .QWidget { border-radius: 15px; border: 1px solid gray;\ padding: 5px; width: 200px; height: 150px; } \ ") - dock['Makerchip-' + str(count)].setVisible(True) - dock['Makerchip-' + str(count)].setFocus() - dock['Makerchip-' + str(count)].raise_() + dock[dockName + str(count)].setVisible(True) + dock[dockName + str(count)].setFocus() + dock[dockName + str(count)].raise_() count = count + 1 @@ -318,31 +343,38 @@ class DockArea(QtWidgets.QMainWindow): def modelicaEditor(self, projDir): """This function sets up the UI for ngspice to modelica conversion.""" global count + + projName = os.path.basename(projDir) + dockName = f'Modelica-{projName}-' + self.modelicaWidget = QtWidgets.QWidget() self.modelicaLayout = QtWidgets.QVBoxLayout() self.modelicaLayout.addWidget(OpenModelicaEditor(projDir)) self.modelicaWidget.setLayout(self.modelicaLayout) - dock['Modelica-' + str(count) - ] = QtWidgets.QDockWidget('Modelica-' + str(count)) - dock['Modelica-' + str(count)].setWidget(self.modelicaWidget) + dock[dockName + str(count) + ] = QtWidgets.QDockWidget(dockName + str(count)) + dock[dockName + str(count)] \ + .setWidget(self.modelicaWidget) self.addDockWidget(QtCore.Qt.TopDockWidgetArea, - dock['Modelica-' + str(count)]) - self.tabifyDockWidget(dock['Welcome'], dock['Modelica-' + str(count)]) + dock[dockName + + str(count)]) + self.tabifyDockWidget(dock['Welcome'], dock[dockName + + str(count)]) - dock['Modelica-' + str(count)].setVisible(True) - dock['Modelica-' + str(count)].setFocus() - dock['Modelica-' + str(count)].raise_() + dock[dockName + str(count)].setVisible(True) + dock[dockName + str(count)].setFocus() + dock[dockName + str(count)].raise_() # CSS - dock['Modelica-' + str(count)].setStyleSheet(" \ + dock[dockName + str(count)].setStyleSheet(" \ .QWidget { border-radius: 15px; border: 1px solid gray;\ padding: 5px; width: 200px; height: 150px; } \ ") temp = self.obj_appconfig.current_project['ProjectName'] if temp: self.obj_appconfig.dock_dict[temp].append( - dock['Modelica-' + str(count)] + dock[dockName + str(count)] ) count = count + 1 diff --git a/src/frontEnd/TerminalUi.py b/src/frontEnd/TerminalUi.py new file mode 100644 index 00000000..4c53548f --- /dev/null +++ b/src/frontEnd/TerminalUi.py @@ -0,0 +1,143 @@ +from PyQt5 import QtCore, QtGui, QtWidgets, uic +import os + + +class TerminalUi(QtWidgets.QMainWindow): + """This is a class that represents the GUI required to provide + details regarding the ngspice simulation. This GUI consists of + a progress bar, a console window which displays the log of the + simulation and button required for re-simulation and cancellation + of the simulation""" + def __init__(self, qProcess, args): + """The constructor of the TerminalUi class + param: qProcess: a PyQt QProcess that runs ngspice + type: qProcess: :class:`QtCore.QProcess` + param: args: arguments to be passed on to the ngspice call + type: args: list + """ + super(TerminalUi, self).__init__() + + # Other variables + self.darkColor = True + self.qProcess = qProcess + self.args = args + self.iconDir = "../../images" + + # Load the ui file + uic.loadUi("TerminalUi.ui", self) + + # Define Our Widgets + self.progressBar = self.findChild( + QtWidgets.QProgressBar, + "progressBar" + ) + self.simulationConsole = self.findChild( + QtWidgets.QTextEdit, + "simulationConsole" + ) + + self.lightDarkModeButton = self.findChild( + QtWidgets.QPushButton, + "lightDarkModeButton" + ) + self.cancelSimulationButton = self.findChild( + QtWidgets.QPushButton, + "cancelSimulationButton" + ) + self.cancelSimulationButton.setEnabled(True) + + self.redoSimulationButton = self.findChild( + QtWidgets.QPushButton, + "redoSimulationButton" + ) + self.redoSimulationButton.setEnabled(False) + + # Add functionalities to Widgets + self.lightDarkModeButton.setIcon( + QtGui.QIcon( + os.path.join( + self.iconDir, + 'light_mode.png' + ) + ) + ) + self.lightDarkModeButton.clicked.connect(self.changeColor) + self.cancelSimulationButton.clicked.connect(self.cancelSimulation) + self.redoSimulationButton.clicked.connect(self.redoSimulation) + + self.simulationCancelled = False + self.show() + + def cancelSimulation(self): + """This function cancels the ongoing ngspice simulation. + """ + self.cancelSimulationButton.setEnabled(False) + self.redoSimulationButton.setEnabled(True) + + if (self.qProcess.state() == QtCore.QProcess.NotRunning): + return + + self.simulationCancelled = True + self.qProcess.kill() + + # To show progressBar completed + self.progressBar.setMaximum(100) + self.progressBar.setProperty("value", 100) + + cancelFormat = '<span style="color:#FF8624; font-size:26px;">{}</span>' + self.simulationConsole.append( + cancelFormat.format("Simulation Cancelled!")) + self.simulationConsole.verticalScrollBar().setValue( + self.simulationConsole.verticalScrollBar().maximum() + ) + + def redoSimulation(self): + """This function reruns the ngspice simulation + """ + self.cancelSimulationButton.setEnabled(True) + self.redoSimulationButton.setEnabled(False) + + if (self.qProcess.state() != QtCore.QProcess.NotRunning): + return + + # To make the progressbar running + self.progressBar.setMaximum(0) + self.progressBar.setProperty("value", -1) + + self.simulationConsole.setText("") + self.simulationCancelled = False + + self.qProcess.start('ngspice', self.args) + + def changeColor(self): + """Toggles the :class:`Ui_Form` console between dark mode + and light mode + """ + if self.darkColor is True: + self.simulationConsole.setStyleSheet("QTextEdit {\n \ + background-color: white;\n \ + color: black;\n \ + }") + self.lightDarkModeButton.setIcon( + QtGui.QIcon( + os.path.join( + self.iconDir, + "dark_mode.png" + ) + ) + ) + self.darkColor = False + else: + self.simulationConsole.setStyleSheet("QTextEdit {\n \ + background-color: rgb(36, 31, 49);\n \ + color: white;\n \ + }") + self.lightDarkModeButton.setIcon( + QtGui.QIcon( + os.path.join( + self.iconDir, + "light_mode.png" + ) + ) + ) + self.darkColor = True diff --git a/src/frontEnd/TerminalUi.ui b/src/frontEnd/TerminalUi.ui new file mode 100644 index 00000000..9039984d --- /dev/null +++ b/src/frontEnd/TerminalUi.ui @@ -0,0 +1,163 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>TerminalUi</class> + <widget class="QWidget" name="TerminalUi"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1244</width> + <height>644</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <widget class="QWidget" name="verticalLayoutWidget"> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>1131</width> + <height>471</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <property name="leftMargin"> + <number>15</number> + </property> + <property name="topMargin"> + <number>15</number> + </property> + <property name="rightMargin"> + <number>15</number> + </property> + <property name="bottomMargin"> + <number>15</number> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QProgressBar" name="progressBar"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>35</height> + </size> + </property> + <property name="styleSheet"> + <string notr="true">QProgressBar::chunk { + background-color: rgb(54,158,225); +}</string> + </property> + <property name="maximum"> + <number>0</number> + </property> + <property name="value"> + <number>-1</number> + </property> + <property name="format"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="redoSimulationButton"> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>35</height> + </size> + </property> + <property name="text"> + <string>Resimulate</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cancelSimulationButton"> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>35</height> + </size> + </property> + <property name="text"> + <string>Cancel Simulation</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="lightDarkModeButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>35</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QTextEdit" name="simulationConsole"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>400</height> + </size> + </property> + <property name="styleSheet"> + <string notr="true">QTextEdit { + background-color: rgb(36, 31, 49); + color: white; +}</string> + </property> + <property name="html"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string> + </property> + <property name="textInteractionFlags"> + <set>Qt::NoTextInteraction</set> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + <resources/> + <connections/> +</ui> |