背景:我在GUI中有几个部分来处理不同的任务。在1部分(portion1),我有文本输入和发送按钮。因此,一旦我将点击发送,它将发送一个数据到我的串口。另一部分(portion2)将从已从其他设备接收到的串行端口接收信号。这两个部分都使用两个按钮;一个按钮用于启动该特定部分的工作,另一个按钮用于停止工作。我使用了全局变量和while循环(用布尔值)退出无限循环,因为我需要不断地发送数据或接收数据。
我的问题是:当我使用全局变量和上面提到的使用无限循环的方式时,如果我单击portion1,portion1将开始迭代。现在,如果我单击portion2,那么portion1将停止。但是我需要同时使用它们,它们都会不断地发送和接收数据,直到我单击其他按钮退出无限循环。
用于澄清的示例代码:
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;我试图找到一个关于互联网的解决方案,但是大多数解决方案都是使用全局变量的。如果我没有全局变量的话,情况会更好。但即使我的要求得到了满足(按照我的问题),它也会奏效。
发布于 2014-01-14 11:47:52
无论全球与否,这里都不是问题所在。
Matlab中的回调都运行在同一个线程上。因此,当callback1运行并触发callback2时,callback2将中断callback1。然后,callback1只在callback2完成后才会继续。您只能使用BusyAction属性稍微修改此过程:
props.html#bqxoija
但这对你的案子没什么帮助。在“适当”的编程语言中,将有一个发送线程和一个接收线程并行运行。但是,你不能这样做,除非你愿意编写java代码。
如果你想坚持使用matlab,最接近线程的是计时器。这些将取代您的while循环。例如,在以下极简例子中:
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因此,这里的sendFcn和recvFcn应该包含在您的should循环中的代码。当然,您可以将period降低到您的需要,我选择了上面的测试目的。
发布于 2014-01-14 11:54:43
您的问题是在回调中执行循环。因此,当单击第二个按钮时,第二个回调将开始并无限循环,直到结束为止。第一个循环将等待第二个回调终止,直到它能够恢复。您需要的是一个执行循环的主程序。嵌套回调将确保它们可以访问和更改局部变量,而不会使它们成为全局变量。如果您对以编程方式构建GUI很满意,请尝试如下:
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中添加一个“开始”按钮,该按钮基本上可以执行上面的程序,只需做一些修改:
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之间。在回调中,您可以更改它们显示的内容:
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按钮时启动)运行循环,只检查切换按钮的状态以确定是否发送和接收。
https://stackoverflow.com/questions/21111172
复制相似问题