Установить значения нескольких флажков в MATLAB - PullRequest
1 голос
/ 20 марта 2019

У меня есть всплывающее окно с 14 флажками (я нажимаю кнопку в моем графическом интерфейсе, открывается другое окно с флажками, я проверяю те, которые мне нужны, и закрываю его), и я хочу установить их значения, если они уже былифлажок.

Я использовал 14 глобальных переменных для значений своих флажков, и я использовал это решение, чтобы установить их значение (таким образом, когда я снова открываю окно, я вижу, какой флажок выбран)

function figure_checkboxes_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);

global checkbox1
global checkbox2 %...to 14

if checkbox1 == 1
    set(handles.checkbox1,'Value',1);
end
if checkbox2 == 1
    set(handles.checkbox2,'Value',1);
end
% 14 if statement for each checkbox

Очевидно, что когда я определяю global checkbox1, это потому, что у меня есть кнопка, которая получает значение каждого флажка (т.е. checkbox1 = get(handles.checkbox1,'Value');)

Есть ли более умный и компактный способ избежать четырнадцати операторов if?

Ответы [ 2 ]

3 голосов
/ 20 марта 2019

Пожалуйста, обратите внимание, я не рекомендую использовать глобальные переменные. Тем не менее, без более подробной информации о вашем коде я буду работать с тем, что вы дали ...

Вы можете использовать одну переменную структуры, хранить все значения флажков и обновлять их в цикле:

function figure_checkboxes_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);

global checkboxValues % Struct with fields 'checkbox1', 'checkbox2', ...

% Loop using dynamic struct field name notation struct.('field')
for icb = 1:14
    cbName = sprintf( 'checkbox%.0f', icb );
    if checkboxValues.(cbName) == 1
        set( handles.(cbName), 'Value', 1 );
    end
end

Вы можете сделать этот вид более обтекаемым, используя arrayfun, для практически той же операции. Заменить цикл следующим:

str = @(icb) sprintf('checkbox%.0f',icb);
arrayfun( @(icb) set( handles.(str(icb)), 'Value', checkboxValues.(str(icb)) ), 1:14 );
3 голосов
/ 20 марта 2019

Это одна из тех проблем, которую можно решить разными способами. Во-первых, я дам вам решение, которое наиболее точно отвечает на ваши вопросы с наименьшим количеством изменений в существующем коде ...

Функции set и get могут работать с векторами дескрипторов, поэтому вы можете свести все это к одному вызову функции, чтобы установить все. Если вы хотите установить только флажки, которые были предварительно отмечены (при условии, что остальные по умолчанию не отмечены), вы можете использовать свои сохраненные состояния флажков как логический индекс в векторе дескрипторов своих флажков:

cbHandles = [handles.checkbox1 handles.checkbox2 ... handles.checkbox14];  % All handles
cbStates = [checkbox1 checkbox2 ... checkbox14];  % All states
set(cbHandles(logical(cbStates)), 'Value', 1);

В качестве альтернативы, вы можете просто установить все состояния (отмеченные или не отмеченные) следующим образом:

set(cbHandles, {'Value'}, num2cell(cbStates(:)));

Как видите, это будет проще, если вы сохраните свои маркеры-флажки и каждый из них будет представлен в виде вектора, а не нескольких переменных.


Альтернативы

Вот несколько альтернативных способов решить или улучшить это, что потребует немного большего изменения существующего кода:

Видимость окна

Вместо того, чтобы повторно открывать и закрывать окно с вашими флажками, вы можете просто создать его один раз, а затем настроить его 'Visibility' свойство , чтобы оно появлялось и исчезало. Даже когда они не видны, все компоненты окна (т.е. флажки) все еще существуют, и к их состояниям можно обращаться с помощью дескрипторов, хранящихся в вашей структуре handles. Это позволяет избежать необходимости сохранять их состояния в глобальных переменных или устанавливать их состояния при повторном открытии окна.

Избегайте глобалов

Структура handles, в отличие от ее имени (поскольку она может называться как угодно), представляет собой обычную структуру , которая может хранить любые данные, а не только графические дескрипторы. В вашей функции закрытия (или там, где вы храните состояния флажков перед закрытием), вы можете просто добавить состояния в структуру handles:

handles.cbStates = get(handles.cbHandles, 'Value');
guidata(hObject, handles);

Предполагается, что ваши маркеры-флажки хранятся в векторе cbHandles. Затем вы обновите состояния в вашей функции открытия следующим образом:

set(handles.cbHandles, {'Value'}, handles.cbStates);
...