我正在使用 GUI 来调用终端命令。通过使用 dos(my_command, '-echo') ,我可以在 Matlab 的命令行窗口中获取命令输出。是否有办法在 GUI 的静态文本中复制 -echo
?
目前,使用 my_command
,我将输出写入 log
文件,并在处理后通过此 log
文件更新静态文本的字符串完成,但我想要的是像命令行窗口中那样的实时 View :输出实时逐行显示。谢谢。
更新:
@Hoki:另一个问题是:当控制台命令正在执行时,如果我关闭 GUI,Matlab 将无法停止地返回错误,如何卡住整个 GUI 直到命令完成?
最佳答案
感谢 Yair Altman 提供的信息 article ,我有一些工作要做,但它涉及侵入 Matlab Java 基础对象(即命令窗口)。
它涉及将监听器附加到 Matlab 命令窗口。现在要小心,经常保存你的工作,并准备好多次终止 Matlab 进程,直到你得到正确的结果......因为每次你的代码中出现错误时,你都会陷入一种无限循环(错误/警告被发送到命令窗口,这会触发您的监听器,从而重新触发错误等...)。我必须重新启动 Matlab 十几次才能让下面的示例稳定运行。
这也是我只临时附加监听器的原因。就在发送 dos 命令之前,我直接删除了监听器。您可以永久离开听众或根据您的需要进行调整,但请记住上面的建议。还要考虑到命令窗口可以容纳大量字符,您可能不希望将所有字符都包含在文本框中,因此您必须管理从中获取的文本(如示例中所示取一个子集),并考虑是否想要追加或只是刷新文本框中的文本。
下面的示例看起来很稳定,任何修改都需要您自担风险;-)
根据评论中的请求,我添加了 3 个功能:
安
onCleanup
。这是一个 Matlab 功能,允许在出现问题时采取最后的行动(一种“捕获所有”机制)。强烈建议此类程序使用未记录的函数。一个
myCloseRequestFcn
,它拦截窗口的关闭操作以删除监听器并避免错误循环。scroll_to_bottom
函数。此选项允许将文本框插入符号移动到文本末尾(= 滚动到底部,以防文本多于可见空间)。
警告:最后一个功能可能需要一个单独的问题,并再次调用未记录的功能(因此永远无法保证兼容性)。为了能够实现它,您需要拥有 findjobj
函数在您的 Matlab 路径中可用。如果您不想下载外部组件,则删除/注释使用它的代码部分和子函数 scroll_to_bottom
(并且忘记滚动文本框,在纯文本中无法做到这一点) MATLAB)。 或者您可以通过查看帖子的编辑历史记录来选择以前版本的代码。
function h = gui_MirrorCmdWindow
%% // just to remove the listener in case something goes wrong
closeup = onCleanup(@() cleanup);
%% // create figure and uicontrol
h.f = figure;
h.txtOut = uicontrol(h.f,'Style','edit','Max',30,'Min',0,...
'HorizontalAlignment','left',...
'FontName','FixedWidth',...
'Units','Normalized',...
'Enable','On',...
'Position',[.05 .2 .9 .75]);
h.btnPing = uicontrol(h.f,'Style','Pushbutton',...
'String','Ping',...
'Units','Normalized',...
'Position',[.05 .05 .9 .1],...
'Callback',@btnPing_callback);
guidata(h.f,h)
%// intercept close request function to cleanup before close
set(gcf,'CloseRequestFcn',@myCloseRequestFcn)
%% // Get the handle of the Matlab control window
jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance;
jCmdWin = jDesktop.getClient('Command Window');
jTextArea = jCmdWin.getComponent(0).getViewport.getView;
%% // Get the handle of the jave edit box panel component
jtxtBox = findjobj(h.txtOut) ;
jTxtPane = jtxtBox.getComponent(0).getComponent(0) ;
%// Save these handles
setappdata( h.f , 'jTextArea', jTextArea ) ;
setappdata( h.f , 'jTxtPane', jTxtPane ) ;
function btnPing_callback(hobj,~)
h = guidata(hobj) ;
jTextArea = getappdata( h.f , 'jTextArea' ) ;
my_command = 'ping google.com -n 10' ;
startPos = jTextArea.getCaretPosition ;
set(jTextArea,'CaretUpdateCallback',{@commandWindowMirror,h.f,startPos}) ;
dos( my_command , '-echo' ) ;
pause(1) %// just to make sure we catch the last ECHO before we kill the callback
set(jTextArea,'CaretUpdateCallback',[]) ;
scroll_to_bottom(h.f)
function commandWindowMirror(~,~,hf,startPos)
h = guidata(hf) ;
jTextArea = getappdata( h.f , 'jTextArea' ) ;
%// retrieve the text since the start position
txtLength = jTextArea.getCaretPosition-startPos ;
if txtLength > 0 %// in case a smart bugger pulled a 'clc' between calls
cwText = char(jTextArea.getText(startPos-1,txtLength) ) ;
end
%// display it in the gui textbox
set( h.txtOut, 'String',cwText ) ;
scroll_to_bottom(h.f)
function scroll_to_bottom(hf)
%// place caret at the end of the texbox (=scroll to bottom)
jTxtPane = getappdata( hf , 'jTxtPane' ) ;
jTxtPane.setCaretPosition(jTxtPane.getDocument.getLength)
function myCloseRequestFcn(hobj,~)
cleanup ; %// make sure we remove the listener
delete(hobj) ; %// delete the figure
function cleanup
jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance;
jCmdWin = jDesktop.getClient('Command Window');
jTextArea = jCmdWin.getComponent(0).getViewport.getView;
set(jTextArea,'CaretUpdateCallback',[]) ;
关于matlab - 将 dos 命令输出显示为静态文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31306845/