Command Window output using Matlab engine in Python

19 次查看(过去 30 天)
I want to be able to see the output printed in the Command Window in real-time while running a script using the Matlab engine in Python (I'm using the Spyder IDE). I've tried two approaches:
Approach 1:
I've started the Matlab engine with desktop using using the following commands:
eng = matlab.engine.start_matlab()
eng.desktop(nargout=0)
The desktop shows up, however all the output that should show in the Matlab Command Window when I run a Matlab script gets printed in the Spyder IDE console.
Approach 2:
Redirecting the standard output and error from Matlab to Python as described here: https://www.mathworks.com/help/matlab/matlab_external/redirect-standard-output-and-error-to-python.html
When using the approach from this Mathworks example, I have to wait for the Matlab script to finish running to see the output, so it doesn't work in real-time.
Does anyone know how I can make this work using either of these approaches or know of a different way of doing this? I am making a GUI using Pyside that can run some data processing with Matlab, but I want to see the progress printed by the Matlab script as it's running. With approach 2, I would just print the Matlab output to a QTextEdit in Pyside

回答(1 个)

Emanuel Mendiola
Emanuel Mendiola 2023-5-12
The example code below generates a simple Python GUI with a QTextEdit and a button that starts the MATLAB engine and runs a MATLAB script that would process data (in this example, it just prints a few things). I want to be able to see the progress of the MATLAB scrip as it's running. For this, I can either start the MATLAB engine in desktop mode and see the MATLAB script output there in the Command Window or print the MATLAB output to the QTextEdit as the script is running.
In the Python script code pasted below, I am running the the script in the background, but when calling future.result() to get the Matlab output/error I have to wait until the Matlab script is finished to get the output/error. So I cannot see the progress of my Matlab script as it's running. Essentially, I want to be able to do this in python:
### pseudocode for desired result
run matlab script
while matlab script is running:
print(matlab script output)
time.sleep(1)
eng.quit()
Alternatively, if I can see the Matlab output in the Command Window, that would also work for me, but when I run the Matlab engine in desktop mode, all the Matlab output is printed on the console window of the Spyder IDE I am using for Python instead.
Python script:
from PySide6.QtWidgets import QApplication,QMainWindow
from PySide6.QtCore import QThread
from PySide6 import QtCore, QtGui, QtWidgets
import io
import matlab.engine
import sys
import time
#GUI is generated
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(342, 265)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.MatlabConsoleOutTextEdit = QtWidgets.QTextEdit(self.centralwidget)
self.MatlabConsoleOutTextEdit.setObjectName("MatlabConsoleOutTextEdit")
self.verticalLayout.addWidget(self.MatlabConsoleOutTextEdit)
self.StartMatlabButton = QtWidgets.QPushButton(self.centralwidget)
self.StartMatlabButton.setObjectName("StartMatlabButton")
self.verticalLayout.addWidget(self.StartMatlabButton)
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 342, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.StartMatlabButton.setText(_translate("MainWindow", "StartMatlabButton"))
#Run Matlab processing in separate QThread
class matlabProcThread(QThread):
#create signal to detect finished thread
finished = QtCore.Signal()
#inherit data from GUI to be available for this class
def __init__(self,parent):
super().__init__()
self.parent = parent
def run(self):
#Start Matlab engine
self.eng = matlab.engine.start_matlab()
self.eng.desktop(nargout=0)
#create matlab structure with options for data processing
opt = {}
#data directory
opt['folder'] = 'C:\\Users'
#Nominal bus voltage
opt['Vn'] = 13.2
#Nominal fundamental frequency
opt['F1nom'] = 60.0
#System frequency
opt['F1'] = 59.87
####################################################################################################################################################
###################################################### Matlab Processing and data progress printing ################################################
####################################################################################################################################################
out = io.StringIO()
err = io.StringIO()
#Run the data processing script wrapper that processes options and runs data processing script
future = self.eng.DataProc(opt,stdout=out,stderr=err,nargout=0,background=True)
#Show data processing progress in QTextEdit while the data processing script is running
future.result()
while not future.done():
self.matlabConsoleOutputWrite(out.getvalue())
time.sleep(1)
self.eng.quit()
self.finished.emit()
####################################################################################################################################################
####################################################################################################################################################
####################################################################################################################################################
#function to write text to the console output text field
def matlabConsoleOutputWrite(self, text):
cursor = self.parent.MatlabConsoleOutTextEdit.textCursor()
cursor.movePosition(QtGui.QTextCursor.End)
cursor.insertText(text)
self.parent.MatlabConsoleOutTextEdit.setTextCursor(cursor)
self.parent.MatlabConsoleOutTextEdit.ensureCursorVisible()
#Run GUI process
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self,parent=None):
super(MainWindow,self).__init__(parent)
self.setupUi(self) #generate GUI
#Start Matlab data processing when button is clicked
self.StartMatlabButton.clicked.connect(self.startProcessing)
def startProcessing(self):
self.statusBar().showMessage("Processing Data",0)
#Create thread
self.ProcessThread = matlabProcThread(self)
#Enable termination
self.ProcessThread.setTerminationEnabled(True)
#Delete contents after finishing
self.ProcessThread.finished.connect(self.ProcessThread.deleteLater)
#Start thread
self.ProcessThread.start()
#Disable start scan button
self.StartMatlabButton.setEnabled(False)
#Enable start scan button again after thread finishes
self.ProcessThread.finished.connect(lambda: self.StartMatlabButton.setEnabled(True))
self.statusBar().clearMessage()
if __name__ == '__main__':
#initiate app instance
if not QApplication.instance():
app = QApplication(sys.argv)
else:
app = QApplication.instance()
Gui = MainWindow()
Gui.show()
sys.exit(app.exec())
Matlab script:
function DataProc(opt)
disp("starting script")
pause(2)
disp(strcat("option Vn: ",num2str(opt.Vn)))
pause(2)
disp(strcat("option F1nom: ",num2str(opt.F1nom)))
pause(2)
disp(strcat("option F1: ",num2str(opt.F1)))
pause(2)
disp("Starting Data Processing...")
addpath(pwd); % Add current directory to path
cd(opt.folder); % Change directory to folder containing data
%% Postprocessing
%run_processing(opt);
end

类别

Help CenterFile Exchange 中查找有关 Call MATLAB from Python 的更多信息

标签

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by