我有一个带有14个复选框的弹出窗口(我在GUI中单击一个按钮,另一个带有复选框的窗口打开,我检查需要的复选框,然后将其关闭),我想设置它们的值(如果已经存在)已选中。
我为复选框的值使用了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语句?
答案 0 :(得分:3)
这是可以用许多不同方式解决的问题之一。首先,我将为您提供最直接回答您的要求的解决方案,只需对现有代码进行最少的修改即可。
set
和get
函数可以在句柄向量上进行操作,因此您可以将其全部简化为仅一个函数调用即可设置所有内容。如果您只想设置以前选中的复选框(假设默认情况下未选中其余复选框),则可以将存储的复选框状态作为logical index使用到复选框句柄的向量中:
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'
property使其显示和消失即可。即使不可见,所有窗口组件(即复选框)仍然存在,并且可以使用存储在handles
结构中的句柄来访问其状态。这样可以避免在重新打开窗口时将它们的状态存储在全局变量中或设置它们的状态。
handles
结构与其名称相反(因为它可以命名为任意名称)只是一个常规的structure,它可以存储任何数据,而不仅仅是图形句柄。在关闭功能(或关闭之前存储复选框状态的任何位置)中,您只需将状态添加到handles
结构中即可:
handles.cbStates = get(handles.cbHandles, 'Value');
guidata(hObject, handles);
这假设您的复选框句柄存储在向量cbHandles
中。然后,您将按如下所示更新打开功能中的状态:
set(handles.cbHandles, {'Value'}, handles.cbStates);
答案 1 :(得分:3)
请预先注意,我不鼓励使用全局变量。但是,如果没有更多代码细节,我将使用您提供的代码...
您可以使用单个struct变量,在其中存储所有复选框值,然后循环更新:
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 );