matlab - 将 dos 命令输出显示为静态文本

标签 matlab batch-file cmd logfile

我正在使用 GUI 来调用终端命令。通过使用 dos(my_command, '-echo') ,我可以在 Matlab 的命令行窗口中获取命令输出。是否有办法在 GUI 的静态文本中复制 -echo

目前,使用 my_command,我将输出写入 log 文件,并在处理后通过此 log 文件更新静态文本的字符串完成,但我想要的是像命令行窗口中那样的实时 View :输出实时逐行显示。谢谢。

更新:

@Hoki:另一个问题是:当控制台命令正在执行时,如果我关闭 GUI,Matlab 将无法停止地返回错误,如何卡住整个 GUI 直到命令完成?

enter image description here

最佳答案

感谢 Yair Altman 提供的信息 article ,我有一些工作要做,但它涉及侵入 Matlab Java 基础对象(即命令窗口)。

commandWindowGui

它涉及将监听器附加到 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/

相关文章:

windows - 如何在 Anaconda 提示中复制/粘贴?

matlab - 在不使用 'for' 循环的情况下访问 MATLAB 中矩阵的所有元素

matlab - 找到元素子集最小值的有效方法

batch-file - 从具有许多子目录的主目录中批量提取特定文件类型

windows - 批处理文件检查其他文件中的字符串

windows - 如何将多个 *.zip 存档文件解压缩到单独的文件夹中?

matlab - 如何从矩阵生成图像(带 float 条目)

Matlab:计算时间序列模型的协方差矩阵的逆

batch-file - Windows 批处理 : Executing command with FOR/F -- "command not found"

batch-file - 如何从 cmd 向 stderr 发送消息?