matlab - 将 dos 命令输出显示为静态文本 [英] matlab - display dos command output to static text

查看:34
本文介绍了matlab - 将 dos 命令输出显示为静态文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 GUI 调用终端命令.通过使用 dos(my_command, '-echo') 我可以在 Matlab 的命令窗口中获得命令输出.无论如何,是否可以在我的 GUI 的静态文本中复制 -echo ?

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

更新:

@Hoki:另一个问题是:当控制台命令正在执行时,如果我关闭 GUI,那么 Matlab 会返回不可停止的错误,如何在命令完成之前冻结整个 GUI?

解决方案

感谢 Yair Altman 提供的信息 .这是一个 Matlab 功能,允许万一出现问题时最后采取行动(一种全能"机制).强烈推荐这种使用未公开函数的程序.

  • A myCloseRequestFcn 拦截窗口的关闭动作以移除监听器并避免错误循环.

  • scroll_to_bottom 函数.这个允许将文本框插入符号移动到文本的末尾(= 滚动到底部以防文本多于可见空间).

  • 警告:最后一个功能可能需要一个单独的问题,并再次要求未记录的功能(因此永远无法保证兼容性).为了能够实现它,您需要拥有 findjobj 函数在您的 Matlab 路径中可用.如果您不想下载外部组件,则删除/注释使用它的代码部分和子函数 scroll_to_bottom(忘记滚动文本框,纯MATLAB).或者您可以通过查看帖子的编辑历史记录来选择之前版本的代码.

    <小时>

    function h = gui_MirrorCmdWindow%%//只是为了在出现问题时移除监听器closeup = onCleanup(@() 清理);%%//创建图形和 uicontrolh.f = 数字;h.txtOut = uicontrol(h.f,'Style','edit','Max',30,'Min',0,...'水平对齐'、'左'、...'字体名称'、'固定宽度'、...单位"、归一化"、...启用"、开启"、...'位置',[.05 .2 .9 .75]);h.btnPing = uicontrol(h.f,'Style','Pushbutton',...'字符串','平',...单位"、归一化"、...'位置',[.05 .05 .9 .1],...'回调',@btnPing_callback);guidata(h.f,h)%//拦截关闭请求函数,在关闭前进行清理设置(gcf,'CloseRequestFcn',@myCloseRequestFcn)%%//获取Matlab控件窗口的句柄jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance;jCmdWin = jDesktop.getClient('命令窗口');jTextArea = jCmdWin.getComponent(0).getViewport.getView;%%//获取jave编辑框面板组件的句柄jtxtBox = findjobj(h.txtOut) ;jTxtPane = jtxtBox.getComponent(0).getComponent(0) ;%//保存这些句柄setappdata( h.f , 'jTextArea', jTextArea ) ;setappdata(h.f, 'jTxtPane', jTxtPane);函数 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) %//只是为了确保我们在终止回调之前捕捉到最后一个 ECHOset(jTextArea,'CaretUpdateCallback',[]) ;滚动到底部(h.f)函数 commandWindowMirror(~,~,hf,startPos)h = guidata(hf) ;jTextArea = getappdata( h.f , 'jTextArea' ) ;%//检索自起始位置起的文本txtLength = jTextArea.getCaretPosition-startPos ;如果 txtLength >0 %//以防智能虫子在调用之间拉出clc"cwText = char(jTextArea.getText(startPos-1,txtLength)) ;结尾%//在gui文本框中显示set( h.txtOut, 'String',cwText ) ;滚动到底部(h.f)函数 scroll_to_bottom(hf)%//将插入符号放在文本框的末尾(=滚动到底部)jTxtPane = getappdata( hf , 'jTxtPane' ) ;jTxtPane.setCaretPosition(jTxtPane.getDocument.getLength)函数 myCloseRequestFcn(hobj,~)清理 ;%//确保我们移除监听器删除(hobj);%//删除图形功能清理jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance;jCmdWin = jDesktop.getClient('命令窗口');jTextArea = jCmdWin.getComponent(0).getViewport.getView;set(jTextArea,'CaretUpdateCallback',[]) ;

    i am using GUI to call a terminal command. By using dos(my_command, '-echo') i can get the command output in Matlab's Command Window. Is there anyway to replicate that -echo in a static text in my GUI?

    Currently, with my_command, I write the output to a log file, and update the static text's String by this log file after process finishes, but what I want is a live-view like in Command Window: output is displayed line by line in real-time. Thanks.

    Update:

    @Hoki: another question is: when the console commands are being executed, if I close the GUI then Matlab returns errors unstopable, how can I freeze the whole GUI until the commands are finished?

    解决方案

    Thanks to Yair Altman info in this article, I got something to work but it involves hacking into Matlab Java base objects (namely the command window).

    It involves attaching a listener to the Matlab command window. Now be careful, save your work often and be prepared to kill Matlab process quite a few times until you get it right ... because every time you have an error in the code you are stuck in a kind of infinite loop (the error/warning is sent to the command window, which triggers your listener, which re-trigger the error etc ...). I had to restart Matlab a good dozen of times just to get the example below to work in a stable way.

    That's also the reason why I only attach the listener temporarily. just before sending the dos command and I remove the listener directly after. You can leave the listener permanently or adjust that to your needs but remember the advice from just above. Also consider that the command window can hold a massive amount of character, which you may not want all in your textbox, so you have to manage the text that you get from it (take a subset as in the example), and consider if you want to append or simply refresh the text in the textbox.

    The example below seems to be stable as it is, any modification at your own risks ;-)

    After request in comment I added 3 functions:

    • An onCleanup. This is a Matlab functionality to allow last resort action in case something goes wrong (a kind of "catch all" mechanism). Heavily recommended for this kind of program using undocumented functions.

    • A myCloseRequestFcn which intercept the closing action of the window to remove the listener and avoid error loops.

    • A scroll_to_bottom function. This one allows to move the text box caret to the end of the text (= to scroll to the bottom in case there is more text than visible space).

    Warning: The last functionality could deserve a separate question and again call for undocumented functionality (so the compatibility is never guaranteed). To be able to implement it you need to have the findjobj function available in your Matlab path. If you do not want to download external component, then delete/comment the part of code that uses it and the subfunction scroll_to_bottom (and forget about scrolling the text box, there is no way to do that in pure Matlab). Or you can pick the previous version of the code by looking at the edit history of the post.


    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 命令输出显示为静态文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆