【问题标题】:Matlab makes the loops run simultaneouslyMatlab 使循环同时运行
【发布时间】:2012-06-16 18:02:54
【问题描述】:

不幸的是,我有两个循环。这就是为什么我的代码让第一个循环运行,并且只有在它完成后,它才会运行第二个循环。

但我希望 gui 同时显示数据:在 hAxes 和 loading1 中。

我该怎么做?

hFigure = figure('units','pixels','position',[300 300 424 470],'menubar','none',...
'name','start processing','numbertitle','off','resize','off');        

hAxes = axes('Parent',hFigure,'Units','pixels','Position',[0 112 424 359]); 

loading1 = uicontrol('style','text','unit','pix','position',[0 72 424 40],...
'backgroundcolor','r','fontsize',20);

%% shows the data on hAxes
for i = 5:100
    if mod(i,2) == 0
        set(hAxes,'Color','b');
    else
        set(hAxes,'Color','g');
    end
    drawnow;
end

%% shows the data on loading1
for i=1:200
    image2 = horzcat('now processing ', 'image', num2str(i), '.jpg of 200 images');
    set(loading1,'string',image2);
    drawnow;
end

这段代码是彼得的:

    function test1

    hFigure = figure('units','pixels','position',[300 300 424 470],'menubar','none','name','start processing','numbertitle','off','resize','off'); 

    % Your other setup calls
    hAxes = axes('Parent',hFigure,'Units','pixels','Position',[0 112 424 359]); 

    loading1 = uicontrol('style','text','unit','pix','position',[0 72 424 40],'backgroundcolor','r','fontsize',20);

    c = 1;
    t = timer('TimerFcn', @color_change_fcn,'StartDelay',1.0);
    start(t);

    for i=1:200
        image2 = horzcat('now processing ', 'image', num2str(i), '.jpg of 200 images');
        set(loading1,'string',image2);
        drawnow;
    end

    function color_change_fcn
        if mod(c,2) == 0
            set(hAxes,'Color','b');
        else
            set(hAxes,'Color','g');
        end
        drawnow;
        c = c + 1;
    end
end

它不起作用(不显示 hAxes)。我看到它没有使 color_change_fcn 运行(我试图在 color_change_fcn 函数的第一行写: disp('test') ,但它什么也没打印。

【问题讨论】:

  • 您可以使用并行计算工具箱和 parfor 构造,但我建议您以某种方式将这两个循环结合起来,以便您具有确定性行为。
  • @Ansari,我知道我可以使用彼得在他的评论中写给我的内容,但我向他解释了原因。请阅读我对他的回答,并告诉我是否可以使用并行计算工具箱做到这一点。

标签: matlab user-interface simultaneous


【解决方案1】:

这似乎与您的previous question 有关,您希望两个循环同时运行(至少看起来是这样)。

@Peter 的回答为基础,考虑以下工作示例:

function timerDemo()
    %# prepare GUI
    hFig = figure('Menubar','none', 'Resize','off');
    axes('XLim',[0 1], 'YLim',[0 1], 'Visible','off', ...
        'Units','normalized', 'Position',[0.1 0.2 0.8 0.6])
    hTxt = uicontrol('Style','text', 'FontSize',24, ...
        'Units','normalized', 'Position',[0 0.9 1 0.1]);
    hPatch = patch([0 0 1 1 0],[0 1 0 1 0],'k');

    %# colors to cycle through
    c = 1;
    clr = lines(4);

    %# create timer
    delay = 0.5;
    hTimer = timer('Period',delay, 'StartDelay',delay, ...
        'ExecutionMode','FixedRate', 'TimerFcn',@timerCallback);

    %# when figure is closed
    set(hFig, 'CloseRequestFcn',@onClose);

    %# process images
    start(hTimer);          %# start timer
    for i=1:100
        if ~ishandle(hFig), break; end

        msg = sprintf('Processing image %d / %d', i, 100);
        set(hTxt, 'String',msg)

        %# some lengthy operation
        pause(.1)
    end
    if isvalid(hTimer)
        stop(hTimer)        %# stop timer
        delete(hTimer)      %# delete timer
    end

    %# timer callback function
    function timerCallback(src,evt)
        if ~ishandle(hFig), return; end

        %# incremenet counter circularly
        c = rem(c,size(clr,1)) + 1;

        %# update color of patch
        set(hPatch, 'FaceColor',clr(c,:));
        drawnow
    end

    %# on figure close
    function onClose(src,evt)
        %# stop and delete timer
        if isvalid(hTimer)
            stop(hTimer);
            delete(hTimer);
        end

        %# call default close callback
        feval(@closereq)
    end
end

该代码模拟对多个图像运行冗长的处理步骤,同时显示动画以保持用户的娱乐。

为了简化代码,我展示了一个不断更新其颜色的补丁(使用计时器)。这代表“正在加载...”的animated GIF image

【讨论】:

  • 我在大学有一个关于图像处理的项目。我对图像处理和matlab一无所知。多亏了你和一些人,我成功地完成了这个项目的很大一部分。太奇妙了!所以我要衷心感谢你!
【解决方案2】:

这是你想要的吗?只需组合循环体。

for i=1:200
    if mod(i,2) == 0
        set(hAxes,'Color','b');
    else
        set(hAxes,'Color','g');
    end

    image2 = horzcat('now processing ', 'image', num2str(i), '.jpg of 200 images');
    set(loading1,'string',image2);
    drawnow;
end

编辑:好的,在这种情况下,尝试使用计时器而不是第一个循环

function output = main_function

% Your other setup calls
hAxes = axes('Parent',hFigure,'Units','pixels','Position',[0 112 424 359]); 

c = 0;
t = timer('TimerFcn', @color_change_fcn, 'Period', 1.0);
start(t);

for i=1:200
    image2 = horzcat('now processing ', 'image', num2str(i), '.jpg of 200 images');
    set(loading1,'string',image2);
    drawnow;
end

function color_change_fcn
    if mod(c,2) == 0
        set(hAxes,'Color','b');
    else
        set(hAxes,'Color','g');
    end
    drawnow;
    c = c + 1;
end
end

请记住,MATLAB 控制流本质上是单线程的,因此如果 MATLAB 正忙于在其他地方工作,这些回调将不会运行。

【讨论】:

  • 不,我只是粘贴一个示例。在我的真实代码中,我必须在第二个循环中计算大量数据,在第一个循环中我想显示图片(直到用户关闭图)。所以如果我知道如何在这个例子中做到这一点,我就会知道如何在我的代码中做到这一点。但感谢您的评论。
  • 嗨,彼得,我更新了主题的代码。请阅读。请注意,在“t = timer(...)”中,我将“Period”一词替换为“StartDelay”。我这样做是因为在“期间”选项中,我收到了一个错误:???为计时器“timer-30”评估 TimerFcn 时出错 输入参数过多。谢谢。
猜你喜欢
  • 2014-06-28
  • 1970-01-01
  • 2023-03-24
  • 2020-02-14
  • 2012-10-16
  • 1970-01-01
  • 1970-01-01
  • 2018-09-06
  • 2020-08-08
相关资源
最近更新 更多