首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MATLAB:在GUI中不使用全局变量而退出无限循环

MATLAB:在GUI中不使用全局变量而退出无限循环
EN

Stack Overflow用户
提问于 2014-01-14 10:28:31
回答 2查看 1.4K关注 0票数 1

背景:我在GUI中有几个部分来处理不同的任务。在1部分(portion1),我有文本输入和发送按钮。因此,一旦我将点击发送,它将发送一个数据到我的串口。另一部分(portion2)将从已从其他设备接收到的串行端口接收信号。这两个部分都使用两个按钮;一个按钮用于启动该特定部分的工作,另一个按钮用于停止工作。我使用了全局变量和while循环(用布尔值)退出无限循环,因为我需要不断地发送数据或接收数据。

我的问题是:当我使用全局变量和上面提到的使用无限循环的方式时,如果我单击portion1,portion1将开始迭代。现在,如果我单击portion2,那么portion1将停止。但是我需要同时使用它们,它们都会不断地发送和接收数据,直到我单击其他按钮退出无限循环。

用于澄清的示例代码:

代码语言:javascript
运行
复制
function send_Callback(hObject, eventdata, handles)
  global firstFlag;
  firstFlag = true;
  while firstFlag
  %Required codes
  end

function haltSend_Callback(hObject, eventdata, handles)
  global firstFlag;
  firstFlag = false;

function receive_Callback(hObject, eventdata, handles)
  global secondFlag;
  secondFlag = true;
  while true
  %Required codes
  end

function stopReceive_Callback(hObject, eventdata, handles)
  global secondFlag;
  secondFlag=false;

我试图找到一个关于互联网的解决方案,但是大多数解决方案都是使用全局变量的。如果我没有全局变量的话,情况会更好。但即使我的要求得到了满足(按照我的问题),它也会奏效。

EN

回答 2

Stack Overflow用户

发布于 2014-01-14 11:47:52

无论全球与否,这里都不是问题所在。

Matlab中的回调都运行在同一个线程上。因此,当callback1运行并触发callback2时,callback2将中断callback1。然后,callback1只在callback2完成后才会继续。您只能使用BusyAction属性稍微修改此过程:

props.html#bqxoija

但这对你的案子没什么帮助。在“适当”的编程语言中,将有一个发送线程和一个接收线程并行运行。但是,你不能这样做,除非你愿意编写java代码。

如果你想坚持使用matlab,最接近线程的是计时器。这些将取代您的while循环。例如,在以下极简例子中:

代码语言:javascript
运行
复制
function cbtest()

    try close('cbtest');end
    f = figure('name', 'cbtest');

    % create the timers:
    period = 0.2; % period in seconds, in which the timer shall execute
    sendTimer = timer('TimerFcn', @sendFcn, 'ExecutionMode', 'fixedDelay', 'Period', period, 'TasksToExecute', Inf);
    recvTimer = timer('TimerFcn', @recvFcn, 'ExecutionMode', 'fixedDelay', 'Period', period, 'TasksToExecute', Inf);

    uicontrol(f, 'position', [10 10 100 25], 'Callback', @(a,b) start(sendTimer), 'string', 'start1');
    uicontrol(f, 'position', [120 10 100 25], 'Callback', @(a,b) stop(sendTimer), 'string', 'stop1');

    uicontrol(f, 'position', [10 50 100 25], 'Callback', @(a,b) start(recvTimer), 'string', 'start2');
    uicontrol(f, 'position', [120 50 100 25], 'Callback', @(a,b) stop(recvTimer), 'string', 'stop2');
end

function sendFcn(hTimer, timerEvt)
    % your send-loop-code
    disp('sending');
end

function recvFcn(hTimer, timerEvt)
    % your receive-loop-code
    disp('receiving');
end

因此,这里的sendFcnrecvFcn应该包含在您的should循环中的代码。当然,您可以将period降低到您的需要,我选择了上面的测试目的。

票数 2
EN

Stack Overflow用户

发布于 2014-01-14 11:54:43

您的问题是在回调中执行循环。因此,当单击第二个按钮时,第二个回调将开始并无限循环,直到结束为止。第一个循环将等待第二个回调终止,直到它能够恢复。您需要的是一个执行循环的主程序。嵌套回调将确保它们可以访问和更改局部变量,而不会使它们成为全局变量。如果您对以编程方式构建GUI很满意,请尝试如下:

代码语言:javascript
运行
复制
function main()
  sendFlag = false;
  receiveFlag = false;

  while true
    if sendFlag
      % Your Sending code
    end
    if receiveFlag
      % Your Receiving code
    end
  end

  function send_Callback(~,~,~)
    sendFlag = true;
  end

  % other Callbacks

end

然后,在按钮的回调(顺便说一句,您可以使用Toggle按钮)中,您只需分别设置sendFlag和receiveFlag。

使用指南,您想要使用切换按钮。我不太清楚指南是如何处理OpeningFcn的,因此您可能应该在GUI中添加一个“开始”按钮,该按钮基本上可以执行上面的程序,只需做一些修改:

代码语言:javascript
运行
复制
function startbutton_Callback(hObject,~,handles)
  while true
    handles = guidata(hObject); % Updates handles structure

    sendFlag = get(handles.sendtoggle, 'Value');
    if sendFlag
      % Your Sending code
    end

    receiveFlag = get(handles.receivetoggle, 'Value');
    if receiveFlag
      % Your Receiving code
    end
  end

另外,创建“发送和接收”按钮,并将其“Min”设置为0,“Max”设置为1。这将使它们在单击“值”属性(在上述循环中读取)时切换到0到1之间。在回调中,您可以更改它们显示的内容:

代码语言:javascript
运行
复制
function send_Callback(hObject,~,handles)
  on = get(hObject,'Value');
  if on
    set(hObject, 'String', 'Stop sending');
  else
    set(hObject, 'String', 'Start sending');
  end
  guidata(hObject,handles); % Update GUI data

现在,您的主函数(在单击start按钮时启动)运行循环,只检查切换按钮的状态以确定是否发送和接收。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21111172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档