Wait until user press return key to continue script
18 ビュー (過去 30 日間)
古いコメントを表示
I have a script plotting a figure with some vertical lines. I then want the user to select some of the lines and output a table with each line's index. I need the script to pause until the user has selected all the lines they want (and press 'enter' to indicate they are finished, for example), and then resume the script to save the selected indices in a table.
Here is my script:
clear, clc, close all
figure
x = rand(1,41);
y = 1:41;
H(1)= plot(x,y,'r.');
H(2)= line([x(21) x(21)],[0 max(y)], 'LineWidth', 2, 'Color', 'k');
H(3)= line([x(3) x(3)],[0 max(y)], 'LineWidth', 2, 'Color', 'k');
H(4)= line([x(15) x(15)],[0 max(y)], 'LineWidth', 2, 'Color', 'k');
set(H, 'ButtonDownFcn', {@LineSelected, H})
% WANT TO PAUSE HERE: WAIT FOR USER TO PRESS RETURN KEY (FOR EXAMPLE)
% THEN RESUME WITH BUILDING THE FOLLOWING TABLE
IndInWorkSpace = reshape(IndInWorkSpace, 2, [])';
ipt_sec = array2table(IndInWorkSpace,'VariableNames',{'start','end'});
ipt_sec.duration = ipt_sec.end - ipt_sec.start;
function LineSelected(ObjectH,EventData, H)
set(ObjectH, 'LineWidth', 4);
set(H(H ~= ObjectH), 'LineWidth', 2);
% Get x and y data of the highlighted lines
ind = ObjectH.XData(1);
if evalin('base','exist(''IndInWorkSpace'',''var'')')
indArray = evalin('base','IndInWorkSpace');
indArray(end+1) = ind;
else
indArray = ind;
end
assignin('base', 'IndInWorkSpace', indArray);
end
Any help appreciated, many thanks!
0 件のコメント
採用された回答
Benjamin Kraus
2021 年 11 月 23 日
x = rand(1,41);
y = 1:41;
H(1)= plot(x,y,'r.');
H(2)= line([x(21) x(21)],[0 max(y)], 'LineWidth', 2, 'Color', 'k');
H(3)= line([x(3) x(3)],[0 max(y)], 'LineWidth', 2, 'Color', 'k');
H(4)= line([x(15) x(15)],[0 max(y)], 'LineWidth', 2, 'Color', 'k');
set(H, 'ButtonDownFcn', {@LineSelected, H})
set(gcf,'WindowKeyPressFcn', @(~,~) set(gcf,'UserData', true));
waitfor(gcf,'UserData')
IndInWorkSpace = reshape(IndInWorkSpace, 2, [])';
ipt_sec = array2table(IndInWorkSpace,'VariableNames',{'start','end'});
ipt_sec.duration = ipt_sec.end - ipt_sec.start;
function LineSelected(ObjectH,EventData, H)
set(ObjectH, 'LineWidth', 4);
set(H(H ~= ObjectH), 'LineWidth', 2);
% Get x and y data of the highlighted lines
ind = ObjectH.XData(1);
if evalin('base','exist(''IndInWorkSpace'',''var'')')
indArray = evalin('base','IndInWorkSpace');
indArray(end+1) = ind;
else
indArray = ind;
end
assignin('base', 'IndInWorkSpace', indArray);
end
その他の回答 (1 件)
Benjamin Kraus
2021 年 11 月 23 日
編集済み: Benjamin Kraus
2021 年 11 月 23 日
One option is to add a WindowKeyPressFcn that runs the rest of your code. Something like this:
x = rand(1,41);
y = 1:41;
H(1)= plot(x,y,'r.');
H(2)= line([x(21) x(21)],[0 max(y)], 'LineWidth', 2, 'Color', 'k');
H(3)= line([x(3) x(3)],[0 max(y)], 'LineWidth', 2, 'Color', 'k');
H(4)= line([x(15) x(15)],[0 max(y)], 'LineWidth', 2, 'Color', 'k');
set(H, 'ButtonDownFcn', {@LineSelected, H})
IndInWorkSpace = [];
set(gcf,'WindowKeyPressFcn', @keyPress)
function LineSelected(ObjectH,EventData, H)
set(ObjectH, 'LineWidth', 4);
set(H(H ~= ObjectH), 'LineWidth', 2);
% Get x and y data of the highlighted lines
ind = ObjectH.XData(1);
if evalin('base','exist(''IndInWorkSpace'',''var'')')
indArray = evalin('base','IndInWorkSpace');
indArray(end+1) = ind;
else
indArray = ind;
end
assignin('base', 'IndInWorkSpace', indArray);
end
function keyPress(~,EventData)
IndInWorkSpace = evalin('base','IndInWorkSpace');
IndInWorkSpace = reshape(IndInWorkSpace, 2, [])';
ipt_sec = array2table(IndInWorkSpace,'VariableNames',{'start','end'});
ipt_sec.duration = ipt_sec.end - ipt_sec.start;
assignin('base', 'ipt_sec', ipt_sec);
end
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Surface and Mesh Plots についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!