MATLAB和全局变量的使用?

发布于 2025-01-02 03:12:10 字数 216 浏览 1 评论 0原文

我正在编写一个用于 dicom 图像和光谱学的工具,我想在我正在制作的函数之间使用很多共享数据。我制作了 GUI,不同的滑块和按钮使用了 dicom 文件中的大量共享数据。

我一直在使用全局变量来存储所有这些函数共享的信息。我目前有很多全局变量。由于耦合性的增加,我被教导要尽可能避免全局变量。在每个函数中从dicom文件中读取数据会更好吗?这似乎是多余的。使用 MATLAB 作为面向对象会有帮助吗?

I am writing a tool for dicom images and spectroscopy and there is a lot of shared data I want to use between the functions I am making. I have GUI that I made and the different sliders and buttons use a lot of this shared data from the dicom files.

I have been using global variables to store information that all of these functions share. I have a lot of globals currently. I have been taught to avoid global variables if possible because of increasing coupling. Would it be better to read in the data from the dicom file in each function? This seems redundant. Would using MATLAB as object-oriented help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

哭了丶谁疼 2025-01-09 03:12:10

我建议使用应用程序数据结构。

应用程序数据是存储为应用程序定义的结构的重要数据,通常附加到 GUI 应用程序或图形窗口。

要使用应用程序数据 (appdata),请使用 setappdatagetappdata 函数。例如,假设您有一个存储为 hGUI 的 GUI 句柄,则以下代码将随机矩阵添加到您的应用程序数据中,然后稍后检索它(摘自 MATLAB 文档)

% Save matrix for later
matrix = randn(35);
setappdata(hGUI, 'mydata', matrix);

% Do some stuff...

% Retrieve my matrix, this could be in a different file to `setappdata`
myMatrix = getappdata(hGUI, 'mydata');

您可以存储本质上任意的数据在您的应用程序数据中,您可以存储它并从任何源文件中获取它,只要 hGUI 引用您的 GUI 应用程序。

I would recommend using application data structures.

Application data is essential data stored as a structure that is defined by your application and is typically attached to a GUI application or figure window.

To use application data (appdata) use the setappdata and getappdata functions. For example, assuming that you have a handle to your GUI stored as hGUI, the following adds a random matrix to your application data and then retrieves it later (lifted from MATLAB documentation)

% Save matrix for later
matrix = randn(35);
setappdata(hGUI, 'mydata', matrix);

% Do some stuff...

% Retrieve my matrix, this could be in a different file to `setappdata`
myMatrix = getappdata(hGUI, 'mydata');

You can store essentially arbitrary data in your application data, and you can store it and get it from any of your source files, as long as hGUI refers to your GUI application.

乜一 2025-01-09 03:12:10

既然您提到您正在使用 GUI 并且想要在控件回调之间共享数据,我建议使用 嵌套函数。整体代码看起来像这样:

function dicomGUI

  %# Initialize your GUI here, linking the control callbacks to the
  %#   nested functions below:

  hLoad = uicontrol('Style', 'push', 'String', 'Load file', ...
                    'Callback', @load_file);
  ...

  %# Initialize the data variables for the DICOM files here:

  data = [];  %# Shared among nested functions
  ...

  %# Below are all the nested functions your controls will use:

  function load_file(hSource, event)
    data = ...;  %# Load the data here
  end
  ...

end

这不仅可以让您将所有 GUI 代码放入一个 m 文件中,而且还简化了控件回调,并使它们可以轻松地共享父函数工作区中的变量 dicomGUI。此方法的示例以及在 GUI 控件之间共享数据的其他建议可以在此文档页面上找到:在 GUI 的回调之间共享数据

正如 Chris 提到的,对于大型且复杂的 GUI,这可能会成为一个非常大的 m 文件。为了在这种情况下保持文件大小较小,我建议将每个回调的主体简单地调用一个单独文件中的函数,该函数接受共享数据变量,执行任何必要的工作,然后将修改后的数据返回到相同的文件中。共享变量。例如:

function transform_callback(hSource, event)

  %# Apply some transform to the data:
  data = transform_data(data);

  %# If the above changes the GUI (disabling controls, changing a
  %#   display, etc.), then those changes should be made here.

end

Since you mention you are working with a GUI and wanting to share data between the control callbacks, I would suggest designing your code using nested functions. The overall code would look something like this:

function dicomGUI

  %# Initialize your GUI here, linking the control callbacks to the
  %#   nested functions below:

  hLoad = uicontrol('Style', 'push', 'String', 'Load file', ...
                    'Callback', @load_file);
  ...

  %# Initialize the data variables for the DICOM files here:

  data = [];  %# Shared among nested functions
  ...

  %# Below are all the nested functions your controls will use:

  function load_file(hSource, event)
    data = ...;  %# Load the data here
  end
  ...

end

Not only does this let you put all your GUI code in one m-file, but it simplifies the control callbacks and makes it easy for them to share variables in the workspace of the parent function dicomGUI. An example of this approach, along with other suggestions for sharing data between GUI controls, can be found on this documentation page: Share Data Among a GUI's Callbacks.

As Chris mentions, this could become a very large m-file for a large and intricate GUI. To keep the file size down in such a case I would suggest making the body of each callback simply a call to a function in a separate file which accepts the shared data variables, performs whatever work is necessary, then returns the modified data to the same shared variables. For example:

function transform_callback(hSource, event)

  %# Apply some transform to the data:
  data = transform_data(data);

  %# If the above changes the GUI (disabling controls, changing a
  %#   display, etc.), then those changes should be made here.

end
分分钟 2025-01-09 03:12:10

一般来说,全局变量是一件坏事。通常有几种更好的方法,其中包括:

  1. 最初读取数据,并将其传递给每个需要它的函数。
  2. 读取数据,每个需要它的函数调用一个返回它的函数。

您可能还需要在返回时以某种方式更新数据包,具体取决于您是仅使用数据还是在使用数据的同时更改数据。

这些想法中的任何一个都应该对您的过程有所帮助。它使您的代码更具可读性,并且不太可能犯某种错误。

Globals as a rule are a bad thing. There are a couple of better ways typically, which include:

  1. Reading in the data initially, and passing it to each function which needs it.
  2. Reading it the data, and each function which needs it calls a function which returns it.

You might need to update the data package upon return somehow as well, depending on if you only use the data or if you change the data as well as using it.

Either one of these ideas should help your process. It makes your code much more readable, and less likely to make some kind of a mistake.

记忆里有你的影子 2025-01-09 03:12:10

由于 MATLAB 的面向对象特性,还有另一种可能性。您可以定义自己的句柄类,并在初始化阶段将其作为附加参数传递给每个回调:

classdef Data<handle
    properties (Access=public)
        Val;
    end
end

function SimpleGui
    data = Data();

    hLoad = uicontrol('Style', 'push', 'String', 'Push me', ...
                      'Callback', {@callback data});
    data.Val = 5;
end

function callback(hSource, event, data)
    data.Val = data.Val+1;
    disp(data.Val);
end

还有另一个选项:

另外,关于 guidata/appdata(如@Chris所述),可以通过以下方式改进:

创建一个始终获取和设置guidata的封装回调:

function CallbackWrapper(hObj,evt,func)
    data = guidata(hObj);
    data = func(hObj,evt,data);
    guidata(hObj,data);
end

现在您的回调应该按以下方式定义(注意不同的签名):

function SimpleGui
    hSave = uicontrol('Style', 'push', 'String', 'Push me', ...
        'Callback', {@CallbackWrapper @myCallBack});
    data.x = 1;
    guidata(hSave,data);
end

function data = myCallBack(hObj,evt,data)
    data.x = data.x + 1;
    disp(data.x);
end

There is another possibility due to the object-oriented nature of MATLAB. You can define your own handle class and pass it in the initialization phase to each callback as an additional argument:

classdef Data<handle
    properties (Access=public)
        Val;
    end
end

function SimpleGui
    data = Data();

    hLoad = uicontrol('Style', 'push', 'String', 'Push me', ...
                      'Callback', {@callback data});
    data.Val = 5;
end

function callback(hSource, event, data)
    data.Val = data.Val+1;
    disp(data.Val);
end

Yet another option:

Also, regarding the guidata/appdata (as described by @Chris), it can be improved in the following way:

Create an encapsulating callback that always gets and sets guidata:

function CallbackWrapper(hObj,evt,func)
    data = guidata(hObj);
    data = func(hObj,evt,data);
    guidata(hObj,data);
end

Now your callbacks should be defined in the following way (note the different signature):

function SimpleGui
    hSave = uicontrol('Style', 'push', 'String', 'Push me', ...
        'Callback', {@CallbackWrapper @myCallBack});
    data.x = 1;
    guidata(hSave,data);
end

function data = myCallBack(hObj,evt,data)
    data.x = data.x + 1;
    disp(data.x);
end
绝對不後悔。 2025-01-09 03:12:10

如果您使用的是 MATLAB 的最新版本之一,则应该利用 OOPS(面向对象编程系统)。

您应该遵守软件设计原则,并从构建合理的软件设计开始。您应该在编写任何代码之前执行此操作。我建议使用 UML 进行软件建模。

If you are using one of the later releases of MATLAB, you should take advantage of the OOPS (object oriented programming system).

You should adhere to software design principles and start by architecting a sound software design. You should do this before writing any code. I recommend using UML for software modeling.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文