【问题标题】:MATLAB programmatic GUI listbox value and data it refers toMATLAB 编程 GUI 列表框值和它引用的数据
【发布时间】:2015-12-20 20:55:26
【问题描述】:

我正在以编程方式制作 GUI,但遇到了一个关于 uicontrol 列表框和每个“值”或“字符串”所指数据的小问题。我觉得这个问题最好用一些代码来说明。这个问题末尾的代码说明了我的问题。

如果您运行此示例,从左侧列表框中选择所有 5 个文件并按“Button1”,您将看到它们进入右侧列表框。然后,您可以在右侧列表框中选择 1 个或多个文件,然后按“Button2”,MATLAB 将输出正确的文件名。这里一切都很好。

如果关闭并重新运行程序,只选择file1、file3和file5,按Button1会使它们再次进入右侧列表框。这就是我的问题所在:如果您现在选择右侧列表框中的所有文件(file1、file3、file3),然后按 Button2,matlab 输出 file1、file2 和 file3... 而不是 file1、file3 和 file5我愿意。

现在我明白为什么会发生这种情况了,因为在列表框中,它的 value 属性从 1 开始并增加,而单元格 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

【问题讨论】:

    标签: matlab user-interface listbox


    【解决方案1】:

    对于这个应用程序,我建议将您的数据存储在 structure 而不是元胞数组中。这将允许您利用 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
    

    现在您的选择返回:

    ans =
    
    file1
    
    
    ans =
    
    file3
    
    
    ans =
    
    file5
    

    正如预期的那样。

    【讨论】:

    • 谢谢,我已将原始程序的数据结构更改为结构,并且运行良好。我要做的一个小改动就是将它从obj.DataSet.(listboxvalues{i}) 更改为obj.DataSet.(listboxvalues{CurrentNum(i)}),否则无论您选择第二个还是第三个,它都会显示第一个文件。完美的解决方案,但谢谢。
    • @SteveHatcher 哎呀,我稍微改变了功能,忘了调整循环。我会在一秒钟内修复它。
    【解决方案2】:

    您可以如下更改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
    

    【讨论】:

    • 嗨,scmg。感谢您的解决方案。这确实只打印出 listbox2 中的文件名,但我有点不知道如何将它带到下一步并仅循环遍历选定的文件(例如,仅文件 1 和 3)。我最终将我的数据结构更改为结构,但如果我想将它们保留为元胞数组,您的解决方案可能会奏效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 2016-10-01
    • 2020-11-19
    • 2014-11-30
    • 2023-03-13
    • 2010-10-21
    相关资源
    最近更新 更多