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

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

问题描述

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



目前, $ c> my_command ,我将输出写入 log 文件,并通过 log 文件在进程完成后,但我想要的是一个实时视图像在命令窗口:输出是逐行显示实时。谢谢。



更新:



@ Hoki:另一个问题是:当执行控制台命令时,if我关闭GUI,然后Matlab返回错误unstopable,如何可以冻结整个GUI,直到命令完成



解决方案

感谢Yair Altman 。这是一个Matlab功能,允许最后的手段,以防万一出现错误(一种捕获所有机制)。使用未归档的功能大力推荐此类程序。


  • A myCloseRequestFcn 可拦截窗口的关闭操作以删除侦听器并避免错误循环。


  • A scroll_to_bottom 功能。这允许将文本框插入符移动到文本的末尾(=如果文本比可见空间多,滚动到底部)。




  • 警告:最后一项功能可能需要一个单独的问题, >无记录的功能(因此不会保证兼容性)。要能够实现它,您需要拥有 findjobj 函数。如果你不想下载外部组件,那么删除/注释使用它的代码部分和子函数 scroll_to_bottom (并且忘记滚动文本框,没有方法在纯Matlab中做)。






      function h = gui_MirrorCmdWindow 

    %% //只是为了在出现错误时删除侦听器
    closeup = onCleanup(@ );

    %% //创建图形和uicontrol
    h.f = figure;
    h.txtOut = uicontrol(hf,'Style','edit','Max',30,'Min',0,...
    'Horizo​​ntalAlignment','left',...
    'FontName','FixedWidth',...
    'Units','Normalized',...
    'Enable','On',...
    '位置',[.0 .2 .9 .75]);

    h.btnPing = uicontrol(hf,'Style','Pushbutton',...
    'String','Ping',...
    'Units' 'normalized',...
    'Position',[。05 .05 .9 .1],...
    'Callback',@ btnPing_callback);

    guidata(hf,h)

    %//截断关闭请求函数以清除close
    set(gcf,'CloseRequestFcn',@ myCloseRequestFcn)

    %% //获取Matlab控件窗口的句柄
    jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance;
    jCmdWin = jDesktop.getClient('Command Window');
    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)%//只是为了确保我们捕获最后一个ECHO之前,我们杀了回调
    set(jTextArea,'CaretUpdateCallback',[]);
    scroll_to_bottom(h.f)


    function commandWindowMirror(〜,〜,hf,startPos)
    h = guidata(hf);
    jTextArea = getappdata(h.f,'jTextArea');

    %//从起始位置检索文本
    txtLength = jTextArea.getCaretPosition-startPos;
    if txtLength> 0%//如果一个聪明的buger在调用之间拉一个'clc'
    cwText = char(jTextArea.getText(startPos-1,txtLength));
    end
    %//在gui文本框中显示
    set(h.txtOut,'String',cwText);
    scroll_to_bottom(hf)


    函数scroll_to_bottom(hf)
    %//在texbox的末尾放置插入符号(=滚动到底部)
    jTxtPane = getappdata(hf,'jTxtPane');
    jTxtPane.setCaretPosition(jTxtPane.getDocument.getLength)


    function myCloseRequestFcn(hobj,〜)
    cleanup; %//确保我们删除侦听器
    delete(hobj); %// delete the figure


    函数cleanup
    jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance;
    jCmdWin = jDesktop.getClient('Command Window');
    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天全站免登陆