在 matlab 中创建未知数量的 uicontrols

Creating an unknown amount of uicontrols in matlab

因此,对于一个自己的项目,我正在 matlab 中创建一个类似 gui 扫雷游戏的游戏,并想创建一个可调节的按钮网格,但我不确定如何操作。这是我目前得到的。

function createField()

xAmount = str2double(inputdlg('enter row length'));
yAmount = str2double(inputdlg('enter column length'));

for i = 1:xAmount
    for j = 1:yAmount
    %create buttons
    end    
end
end

与大多数问题一样,有许多不同的方法,写了类似的东西后,我会给你我在编写辅助函数时使用的相同提示。


您的代码将根据按下的按钮进行操作,因此每个按钮都需要自己唯一的 ID 和属性。根据所使用的 MATLAB 版本,您的每个图形元素都会有一个 handle。从 R2014b 开始,图形对象可以直接作为对象寻址,而不需要使用数字 ID 作为指针。

从图 window 开始,查看 figure properties:

h.mainfig = figure; % Arbitrary figure window
get(h.mainfig); % Dump properties to command window

现在我们可能最感兴趣的是主图 window 的 UnitsPosition 属性,您可以在辅助函数中使用它们来了解如何大小和 space 创建按钮时的大小。

如果我们用 uicontrol() we're going to get mostly the same properties 创建一个按钮图形对象。

h.randombutton = uicontrol('Parent', h.mainfig, 'Style', 'pushbutton');
get(h.randombutton);

同样,我们对 UnitsPosition 属性感兴趣。我们还将对 Callback 属性 感兴趣,这是在我们与按钮交互时执行的函数。另一个不错的是 Tag 属性,它可以用来为每个按钮设置一个唯一的字符串标签,以供后面的逻辑使用。


您可能已经注意到我正在使用 structure array to store my graphics handles. This is similar to how MATLAB generates its object data when creating a GUI with GUIDE and has the huge advantage of a tidy data package to pass around our function. A great thing about structure arrays is that you can nest data structures, allowing us to easily generate and address graphics objects without needing to get clever with dynamic field references or eval()(糟糕)。不必执行 button_1button_2 等操作,我们可以这样做:

h.button(1) = uicontrol('Parent', h.mainfig, 'Style', 'pushbutton');
h.button(2) = uicontrol('Parent', h.mainfig, 'Style', 'pushbutton');
...
h.button(n) = uicontrol('Parent', h.mainfig, 'Style', 'pushbutton');

现在我们知道如何以编程方式生成任意数量的按钮并在以后轻松解决它们。


除了按钮生成,我们还有一个我之前提到的关键函数,按钮回调。回调函数遵循 slightly different syntax,因为它们本机传递两个参数,正在执行回调的对象的句柄和事件数据结构(有关更多信息,请参阅文档)。因为该函数知道 UI 对象调用了它,所以我们可以创建一个非常通用的函数。

希望这对您有所帮助!

一个解决方案可能是:

function create_field(hparent, nx, ny, width, padding)

        % Test arguments
        if ~test_parent_handle(hparent)
                error('Parent must be a single valid graphic handle.');
        elseif ~test_positive_integer(nx)
                error('Number of buttons on X direction must be a scalar positive integer.');
        elseif ~test_positive_integer(ny)
                error('Number of buttons on Y direction must be a scalar positive integer.');
        elseif ~test_positive_integer(width) ...
        || (width >= 100)
                error('Button width must be a scalar positive integer smaller than 100.');
        elseif ~test_positive_integer(padding) ...
        || (padding >= 20)
                error('Button padding must be a scalar positive integer smaller than 20.');
        end;

        % Resize the parent to fit the button grid
        set(hparent, 'Units', 'pixels');
        ppos = get(hparent, 'Position');
        ppos(3) = nx*width + (nx-1)*padding;
        ppos(4) = ny*width + (ny-1)*padding;
        set(hparent, 'Position', ppos);

        % Create button grid
        for p = 1:nx
                for q = 1:ny
                        bpos = [                  % Button spec:
                           (p-1)*(width+padding)  %  - X
                           (q-1)*(width+padding)  %  - Y
                           width                  %  - W
                           width                  %  - H
                        ];
                        uicontrol(                              ...
                           'Units',     'pixels',               ...
                           'Tag',       sprintf('X%dY%d',p,q),  ...
                           'Style',     'pushbutton',           ...
                           'Parent',    hparent,                ...
                           'Position',  bpos                    ...                   
                        );
                end;
        end;

        % ----- NESTED FUNCTIONS -----
        function tf = test_parent_handle(value)
                tf = isscalar(value) ...
                  && ishandle(value);
        end

        function tf = test_positive_integer(value)
                tf = isscalar(value) ...
                  && isreal(value) ...
                  && isfinite(value) ...
                  && (value > 0) ...
                  && (fix(value) == value);
        end
end

对于具有 15 x 10 方形按钮的图形,每个按钮的边长为 25 像素,按钮之间的填充为 3 像素,请调用:

create_field(figure(), 15, 10, 20, 3);

您是否考虑过在 Java 中创建 ui - 未记录的 matlab 有一些 examples. Java would provide you nice LayoutManagers 可以处理调整大小等问题。