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

符合预期。