MATLAB 编程 GUI 列表框值及其引用的数据
MATLAB programmatic GUI listbox value and data it refers to
我正在以编程方式制作 GUI,并且 运行 提出了一个关于 uicontrol 列表框和每个 'value' 或 'string' 引用的数据的小问题。我觉得这个问题最好用一些代码来说明。这个问题末尾的代码说明了我的问题。
如果您 运行 这个例子,select 左侧列表框中的所有 5 个文件并按 'Button1',您将看到它们进入右侧列表框。然后,您可以 select 1,或右侧列表框中的几个文件,然后按 'Button2' ,MATLAB 将输出正确的文件名。这里一切都很好。
如果关闭并重新运行 程序,只有select file1、file3 和file5,按Button1 将使它们再次进入右侧列表框。这就是我的问题所在:如果 select 现在右侧列表框中的所有文件(file1、file3、file3),然后按 Button2,matlab 输出 file1、file2 和 file3... 而不是 file1, file3 和 file5 随心所欲。
现在我明白为什么会这样了,因为在列表框中它的 value
属性 从 1 开始递增,而 Cell DataSet
中的基础数据保持有序 file1到 file5... 所以 value
1 2 3 指的是 DataSet{1}
DataSet{2}
DataSet{3}
...
克服这个问题的最佳方法是什么?我想补充一点,对于我的实际 GUI,文件名可能并不总是那么明显。
classdef example < handle
properties
Figure;
Button1;
Button2;
ListBox1;
ListBox2;
DataSet = {};
end
methods
function obj = example()
create(obj);
makeUpData(obj);
end
function create(obj)
obj.Figure = figure('Position',[300 300 640 640]);
obj.Button1 = uicontrol('Style','pushbutton','String','Button1',...
'Position',[240 260 80 40],'Callback',@obj.button1CB);
obj.Button2 = uicontrol('Style','pushbutton','String','Button2',...
'Position',[510 260 80 40],'Callback',@obj.button2CB);
obj.ListBox1 = uicontrol('Style','listbox','String','',...
'Position',[50 250 145 100],'Max',3);
obj.ListBox2 = uicontrol('Style','listbox','String','',...
'Position',[350 250 145 100],'Max',3);
end
function makeUpData(obj)
obj.DataSet = {'file1' 'file2' 'file3' 'file4' 'file5'};
obj.ListBox1.String = obj.DataSet;
end
function button1CB(obj,hObject,eventdata)
CurrentNum = get(obj.ListBox1,'Value');
NameListBox1 = get(obj.ListBox1,'String');
NewName = obj.ListBox2.String;
for i = 1:numel(CurrentNum)
NewName{end+1} = [NameListBox1{CurrentNum(i)}];
end
obj.ListBox2.String = NewName;
end
function button2CB(obj,hObject,eventdata)
CurrentNum = get(obj.ListBox2,'Value')
for i = 1:numel(CurrentNum)
obj.DataSet{CurrentNum(i)}
end
end
end
end
你可以改变Button2
的回调函数如下,使用ismember
获取obj.DataSet
中对应的索引:
function button2CB(obj,hObject,eventdata)
selected = cellstr(get(obj.ListBox2, 'String'));
referred = ismember(obj.DataSet, selected);
obj.DataSet(referred)
obj.DataSet{referred}
end
对于此应用程序,我建议将您的数据存储在 structure rather than a cell array. This will allow you to utilize dynamic field references 中以访问您的数据,而不必担心从文件名转换为元胞数组中的索引。
我修改了你的properties
定义:
properties
Figure;
Button1;
Button2;
ListBox1;
ListBox2;
DataSet = struct;
end
您的makeUpData
定义:
function makeUpData(obj)
dummydata = {'file1' 'file2' 'file3' 'file4' 'file5'};
for ii = 1:length(dummydata)
obj.DataSet.(dummydata{ii}) = dummydata{ii};
end
obj.ListBox1.String = fieldnames(obj.DataSet);
end
你的 button2CB
定义:
function button2CB(obj,hObject,eventdata)
listboxvalues = get(obj.ListBox2, 'String');
CurrentNum = get(obj.ListBox2,'Value');
for i = 1:numel(CurrentNum)
obj.DataSet.(listboxvalues{CurrentNum(i)})
end
end
现在你的选择returns:
ans =
file1
ans =
file3
ans =
file5
符合预期。
我正在以编程方式制作 GUI,并且 运行 提出了一个关于 uicontrol 列表框和每个 'value' 或 'string' 引用的数据的小问题。我觉得这个问题最好用一些代码来说明。这个问题末尾的代码说明了我的问题。
如果您 运行 这个例子,select 左侧列表框中的所有 5 个文件并按 'Button1',您将看到它们进入右侧列表框。然后,您可以 select 1,或右侧列表框中的几个文件,然后按 'Button2' ,MATLAB 将输出正确的文件名。这里一切都很好。
如果关闭并重新运行 程序,只有select file1、file3 和file5,按Button1 将使它们再次进入右侧列表框。这就是我的问题所在:如果 select 现在右侧列表框中的所有文件(file1、file3、file3),然后按 Button2,matlab 输出 file1、file2 和 file3... 而不是 file1, file3 和 file5 随心所欲。
现在我明白为什么会这样了,因为在列表框中它的 value
属性 从 1 开始递增,而 Cell DataSet
中的基础数据保持有序 file1到 file5... 所以 value
1 2 3 指的是 DataSet{1}
DataSet{2}
DataSet{3}
...
克服这个问题的最佳方法是什么?我想补充一点,对于我的实际 GUI,文件名可能并不总是那么明显。
classdef example < handle
properties
Figure;
Button1;
Button2;
ListBox1;
ListBox2;
DataSet = {};
end
methods
function obj = example()
create(obj);
makeUpData(obj);
end
function create(obj)
obj.Figure = figure('Position',[300 300 640 640]);
obj.Button1 = uicontrol('Style','pushbutton','String','Button1',...
'Position',[240 260 80 40],'Callback',@obj.button1CB);
obj.Button2 = uicontrol('Style','pushbutton','String','Button2',...
'Position',[510 260 80 40],'Callback',@obj.button2CB);
obj.ListBox1 = uicontrol('Style','listbox','String','',...
'Position',[50 250 145 100],'Max',3);
obj.ListBox2 = uicontrol('Style','listbox','String','',...
'Position',[350 250 145 100],'Max',3);
end
function makeUpData(obj)
obj.DataSet = {'file1' 'file2' 'file3' 'file4' 'file5'};
obj.ListBox1.String = obj.DataSet;
end
function button1CB(obj,hObject,eventdata)
CurrentNum = get(obj.ListBox1,'Value');
NameListBox1 = get(obj.ListBox1,'String');
NewName = obj.ListBox2.String;
for i = 1:numel(CurrentNum)
NewName{end+1} = [NameListBox1{CurrentNum(i)}];
end
obj.ListBox2.String = NewName;
end
function button2CB(obj,hObject,eventdata)
CurrentNum = get(obj.ListBox2,'Value')
for i = 1:numel(CurrentNum)
obj.DataSet{CurrentNum(i)}
end
end
end
end
你可以改变Button2
的回调函数如下,使用ismember
获取obj.DataSet
中对应的索引:
function button2CB(obj,hObject,eventdata)
selected = cellstr(get(obj.ListBox2, 'String'));
referred = ismember(obj.DataSet, selected);
obj.DataSet(referred)
obj.DataSet{referred}
end
对于此应用程序,我建议将您的数据存储在 structure rather than a cell array. This will allow you to utilize dynamic field references 中以访问您的数据,而不必担心从文件名转换为元胞数组中的索引。
我修改了你的properties
定义:
properties
Figure;
Button1;
Button2;
ListBox1;
ListBox2;
DataSet = struct;
end
您的makeUpData
定义:
function makeUpData(obj)
dummydata = {'file1' 'file2' 'file3' 'file4' 'file5'};
for ii = 1:length(dummydata)
obj.DataSet.(dummydata{ii}) = dummydata{ii};
end
obj.ListBox1.String = fieldnames(obj.DataSet);
end
你的 button2CB
定义:
function button2CB(obj,hObject,eventdata)
listboxvalues = get(obj.ListBox2, 'String');
CurrentNum = get(obj.ListBox2,'Value');
for i = 1:numel(CurrentNum)
obj.DataSet.(listboxvalues{CurrentNum(i)})
end
end
现在你的选择returns:
ans =
file1
ans =
file3
ans =
file5
符合预期。