खोज…


यूजर इंटरफेस के आसपास डाटा पास करना

अधिकांश उन्नत उपयोगकर्ता इंटरफ़ेस के लिए उपयोगकर्ता को उन विभिन्न कार्यों के बीच जानकारी पारित करने में सक्षम होना पड़ता है जो उपयोगकर्ता इंटरफ़ेस बनाते हैं। MATLAB ऐसा करने के लिए विभिन्न तरीकों की एक संख्या है।


guidata

MATLAB का अपना GUI डेवलपमेंट एनवायरनमेंट (GUIDE) कॉलबैक के बीच डेटा पास करने के लिए एक struct नाम के handles का इस्तेमाल करना पसंद करता है। इस struct में विभिन्न UI घटकों के साथ-साथ उपयोगकर्ता-निर्दिष्ट डेटा के सभी ग्राफिक्स हैंडल शामिल हैं। यदि आप एक गाइड-निर्मित कॉलबैक जो स्वचालित रूप से गुजरता है का उपयोग नहीं कर रहे हैं, तो handles , आप का उपयोग कर मौजूदा मूल्य प्राप्त कर सकते हैं guidata

% hObject is a graphics handle to any UI component in your GUI
handles = guidata(hObject);

यदि आप इस डेटा संरचना में संग्रहीत मान को संशोधित करना चाहते हैं, तो आप संशोधित कर सकते हैं, लेकिन फिर आपको अन्य कॉलबैक द्वारा दिखाई देने वाले परिवर्तनों के लिए इसे hObject भीतर संग्रहीत करना होगा। आप इसे एक दूसरे इनपुट तर्क के लिए guidata करके निर्दिष्ट कर सकते हैं।

% Update the value
handles.myValue = 2;

% Save changes
guidata(hObject, handles)

hObject का मान hObject मायने नहीं रखता है जब तक वह एक ही figure भीतर UI घटक है क्योंकि अंततः डेटा को hObject वाले आंकड़े में संग्रहीत किया जाता है।

के लिए सबसे अच्छा:

  • handles संरचना को संग्रहीत करना, जिसमें आप अपने जीयूआई घटकों के सभी हैंडल स्टोर कर सकते हैं।
  • "छोटे" अन्य चर को संग्रहीत करना, जिन्हें अधिकांश कॉलबैक द्वारा एक्सेस करने की आवश्यकता होती है।

इसके लिए अनुशंसित नहीं :

  • बड़े चर संग्रहीत करना जो सभी कॉलबैक और उप-कार्यों (इन के लिए setappdata / getappdata उपयोग करना) तक getappdata

setappdata / getappdata

guidata दृष्टिकोण के समान, आप ग्राफिक्स हैंडल के भीतर से मानों को संग्रहीत करने और पुनः प्राप्त करने के लिए setappdata और getappdata का उपयोग कर सकते हैं। इन विधियों का उपयोग करने का लाभ यह है कि आप सभी संग्रहीत डेटा वाले संपूर्ण struct बजाय केवल वही मान प्राप्त कर सकते हैं जो आप चाहते हैं । यह एक कुंजी / मूल्य स्टोर के समान है।

एक ग्राफिक्स ऑब्जेक्ट के भीतर डेटा को स्टोर करने के लिए

% Create some data you would like to store
myvalue = 2

% Store it using the key 'mykey'
setappdata(hObject, 'mykey', myvalue)

और एक अलग कॉलबैक के भीतर से उसी मूल्य को पुनः प्राप्त करने के लिए

value = getappdata(hObject, 'mykey');

नोट: यदि कोई मूल्य getappdata को कॉल करने से पहले संग्रहीत नहीं किया गया था, तो यह एक खाली सरणी ( [] ) वापस कर देगा।

guidata समान, डेटा उस आंकड़े में संग्रहीत होता है जिसमें hObject होता है।

के लिए सबसे अच्छा:

  • बड़े चर संग्रहीत करना, जिन्हें सभी कॉलबैक और उप-कार्यों द्वारा एक्सेस नहीं करना पड़ता है।

UserData

हर ग्राफिक्स के हैंडल में एक विशेष गुण होता है, UserData जिसमें कोई भी डेटा हो सकता है जिसे आप चाहते हैं। इसमें एक सेल ऐरे, एक struct या एक स्केलर हो सकता है। आप इस संपत्ति का लाभ उठा सकते हैं और इस क्षेत्र में दिए गए ग्राफिक्स हैंडल से जुड़े किसी भी डेटा को स्टोर कर सकते हैं। यदि आप R2014b या नए का उपयोग कर रहे हैं, तो आप ग्राफिक्स ऑब्जेक्ट या डॉट नोटेशन के लिए मानक get / set विधियों का उपयोग करके मूल्य को बचा सकते हैं और प्राप्त कर सकते हैं।

% Create some data to store
mydata = {1, 2, 3};

% Store it within the UserData property
set(hObject, 'UserData', mydata)

% Of if you're using R2014b or newer:
% hObject.UserData = mydata;

फिर एक अन्य कॉलबैक से, आप इस डेटा को पुनः प्राप्त कर सकते हैं:

their_data = get(hObject, 'UserData');

% Or if you're using R2014b or newer:
% their_data = hObject.UserData;

के लिए सबसे अच्छा:

  • एक सीमित दायरे के साथ चर को संग्रहीत करना (चर जो केवल उस वस्तु द्वारा उपयोग किए जाने की संभावना है जिसमें वे संग्रहीत होते हैं, या वस्तुओं का इसका सीधा संबंध होता है)।

नेस्टेड कार्य

MATLAB में, एक नेस्टेड फ़ंक्शन मूल फ़ंक्शन में परिभाषित किसी भी चर को पढ़ और संशोधित कर सकता है। इस तरह, यदि आप कॉलबैक को नेस्टेड फ़ंक्शन के रूप में निर्दिष्ट करते हैं, तो यह मुख्य फ़ंक्शन में संग्रहीत किसी भी डेटा को पुनः प्राप्त और संशोधित कर सकता है।

function mygui()    
    hButton = uicontrol('String', 'Click Me', 'Callback', @callback);

    % Create a counter to keep track of the number of times the button is clicked
    nClicks = 0;

    % Callback function is nested and can therefore read and modify nClicks
    function callback(source, event)
        % Increment the number of clicks
        nClicks = nClicks + 1;

        % Print the number of clicks so far
        fprintf('Number of clicks: %d\n', nClicks);
    end
end

के लिए सबसे अच्छा:

  • छोटे, सरल GUIs। (त्वरित प्रोटोटाइप के लिए, guidata और / या set/getappdata विधियों को लागू नहीं करना है)।

इसके लिए अनुशंसित नहीं :

  • मध्यम, बड़े या जटिल जीयूआई।

  • GUI GUIDE के साथ बनाया गया।


स्पष्ट इनपुट तर्क

यदि आपको कॉलबैक फ़ंक्शन में डेटा भेजने की आवश्यकता है और कॉलबैक के भीतर डेटा को संशोधित करने की आवश्यकता नहीं है, तो आप हमेशा सावधानीपूर्वक तैयार की गई कॉलबैक परिभाषा का उपयोग करके कॉलबैक में डेटा पास करने पर विचार कर सकते हैं।

आप एक अनाम फ़ंक्शन का उपयोग कर सकते हैं जो इनपुट जोड़ता है

% Create some data to send to mycallback
data = [1, 2, 3];

% Pass data as a third input to mycallback
set(hObject, 'Callback', @(source, event)mycallback(source, event, data))

या आप कॉलबैक निर्दिष्ट करने के लिए सेल सरणी सिंटैक्स का उपयोग कर सकते हैं, फिर से अतिरिक्त इनपुट निर्दिष्ट कर सकते हैं।

set(hObject, 'Callback', {@mycallback, data})

के लिए सबसे अच्छा:

  • जब कॉलबैक को कुछ ऑपरेशन करने के लिए data आवश्यकता होती है, लेकिन data चर को नए राज्य में संशोधित और सहेजने की आवश्यकता नहीं होती है।

अपने यूआई में एक बटन बनाना जो कॉलबैक निष्पादन को रोक देता है

कभी-कभी हम एप्लिकेशन की स्थिति का निरीक्षण करने के लिए कोड निष्पादन को रोकना चाहते हैं ( डीबगिंग देखें)। MATLAB संपादक के माध्यम से कोड चलाते समय, यह यूआई में "पॉज़" बटन का उपयोग करके या Ctrl + c (विंडोज पर) दबाकर किया जा सकता है। हालांकि, जब जीयूआई (कुछ uicontrol के कॉलबैक के माध्यम से) से गणना शुरू की गई थी, तो यह विधि अब काम नहीं करती है, और कॉलबैक को एक अन्य कॉलबैक के माध्यम से बाधित किया जाना चाहिए। नीचे इस सिद्धांत का प्रदर्शन है:

function interruptibleUI
dbclear in interruptibleUI % reset breakpoints in this file
figure('Position',[400,500,329,160]); 

uicontrol('Style', 'pushbutton',...
          'String', 'Compute',...
          'Position', [24 55 131 63],...
          'Callback', @longComputation,...
          'Interruptible','on'); % 'on' by default anyway
      
uicontrol('Style', 'pushbutton',...
          'String', 'Pause #1',...
          'Position', [180 87 131 63],...
          'Callback', @interrupt1);       

uicontrol('Style', 'pushbutton',...
          'String', 'Pause #2',...
          'Position', [180 12 131 63],...
          'Callback', @interrupt2);    

end

function longComputation(src,event)
  superSecretVar = rand(1);
  pause(15);
  print('done!'); % we'll use this to determine if code kept running "in the background".
end

function interrupt1(src,event) % depending on where you want to stop
  dbstop in interruptibleUI at 27 % will stop after print('done!');
  dbstop in interruptibleUI at 32 % will stop after **this** line.
end

function interrupt2(src,event) % method 2
  keyboard;
  dbup; % this will need to be executed manually once the code stops on the previous line.
end

यह सुनिश्चित करने के लिए कि आप इस उदाहरण को निम्न करते हैं:

  1. उपर्युक्त कोड को एक नई फ़ाइल में पेस्ट करें और इसे interruptibleUI.m रूप में सहेजें, जैसे कि कोड फ़ाइल की पहली पंक्ति पर शुरू होता है (यह काम करने के लिए 1 विधि के लिए महत्वपूर्ण है)।
  2. स्क्रिप्ट चलाएँ।
  3. गणना पर क्लिक करें और कुछ ही समय बाद # 1 रोकें या # 2 रोकें पर क्लिक करें।
  4. सुनिश्चित करें कि आप superSecretVar का मूल्य पा सकते हैं।

"हैंडल" संरचना का उपयोग करके डेटा पास करना

यह दो बटन वाले मूल GUI का एक उदाहरण है जो GUI के handles संरचना में संग्रहीत मान को बदलता है।

function gui_passing_data()
    % A basic GUI with two buttons to show a simple use of the 'handles'
    % structure in GUI building

    %  Create a new figure.
    f = figure();

    % Retrieve the handles structure
    handles = guidata(f);

    % Store the figure handle
    handles.figure = f;

    % Create an edit box and two buttons (plus and minus), 
    % and store their handles for future use
    handles.hedit  = uicontrol('Style','edit','Position',[10,200,60,20] , 'Enable', 'Inactive');

    handles.hbutton_plus  = uicontrol('Style','pushbutton','String','+',...
               'Position',[80,200,60,20] , 'Callback' , @ButtonPress);

    handles.hbutton_minus  = uicontrol('Style','pushbutton','String','-',...
               'Position',[150,200,60,20] , 'Callback' , @ButtonPress);

    % Define an initial value, store it in the handles structure and show
    % it in the Edit box
    handles.value = 1;
    set(handles.hedit , 'String' , num2str(handles.value))

    % Store handles
    guidata(f, handles);



function  ButtonPress(hObject, eventdata)
    % A button was pressed
    % Retrieve the handles
    handles = guidata(hObject);

    % Determine which button was pressed; hObject is the calling object
    switch(get(hObject , 'String'))
        case '+'
            % Add 1 to the value
            handles.value = handles.value + 1;
            set(handles.hedit , 'String', num2str(handles.value))
        case '-'
            % Substract 1 from the value
            handles.value = handles.value - 1;
    end

    % Display the new value
    set(handles.hedit , 'String', num2str(handles.value))

    % Store handles
    guidata(hObject, handles);

उदाहरण का परीक्षण करने के लिए, इसे gui_passing_data.m नामक फ़ाइल में gui_passing_data.m और F5 के साथ लॉन्च करें। कृपया ध्यान दें कि इस तरह के एक सरल मामले में, आपको हैंडल संरचना में मूल्य को संग्रहीत करने की भी आवश्यकता नहीं होगी, क्योंकि आप इसे सीधे संपादित बॉक्स की String संपत्ति से एक्सेस कर सकते हैं।

उपयोगकर्ता इंटरफ़ेस के आसपास डेटा पास करते समय प्रदर्शन समस्याएँ

दो मुख्य तकनीकें जीयूआई फ़ंक्शन और कॉलबैक के बीच डेटा पास करने की अनुमति देती हैं: सेटपडेटा / गेटपडेटा और गाइडटा ( अधिक जानकारी पढ़ें )। पूर्व का उपयोग बड़े चर के लिए किया जाना चाहिए क्योंकि यह अधिक समय कुशल है। निम्न उदाहरण दो तरीकों की दक्षता का परीक्षण करता है।

एक साधारण बटन के साथ एक GUI बनाया गया है और एक बड़ा चर (10000x10000 डबल) गाइडटाटा और सेटपडेटा दोनों के साथ संग्रहीत किया गया है। बटन अपने निष्पादन के समय दो तरीकों का उपयोग करके चर को फिर से लोड और संग्रहीत करता है। सेटपैडटा का उपयोग करके चलने का समय और प्रतिशत सुधार कमांड विंडो में प्रदर्शित होते हैं।

function gui_passing_data_performance()
    % A basic GUI with a button to show performance difference between
    % guidata and setappdata

    %  Create a new figure.
    f = figure('Units' , 'normalized');

    % Retrieve the handles structure
    handles = guidata(f);

    % Store the figure handle
    handles.figure = f;

    handles.hbutton = uicontrol('Style','pushbutton','String','Calculate','units','normalized',...
               'Position',[0.4 , 0.45 , 0.2 , 0.1] , 'Callback' , @ButtonPress);

    % Create an uninteresting large array
    data = zeros(10000);

    % Store it in appdata
    setappdata(handles.figure , 'data' , data);

    % Store it in handles
    handles.data = data;

    % Save handles
    guidata(f, handles);



function  ButtonPress(hObject, eventdata)

    % Calculate the time difference when using guidata and appdata
    t_handles = timeit(@use_handles);
    t_appdata = timeit(@use_appdata);

    % Absolute and percentage difference
    t_diff = t_handles - t_appdata;
    t_perc = round(t_diff / t_handles * 100);

    disp(['Difference: ' num2str(t_diff) ' ms / ' num2str(t_perc) ' %'])




function  use_appdata()  

    % Retrieve the data from appdata
    data = getappdata(gcf , 'data');

    % Do something with data %

    % Store the value again
    setappdata(gcf , 'data' , data);


function use_handles()

    % Retrieve the data from handles
    handles = guidata(gcf);
    data = handles.data;

    % Do something with data %

    % Store it back in the handles
    handles.data = data;
    guidata(gcf, handles);

मेरे Xeon [email protected] GHz पर मुझे Difference: 0.00018957 ms / 73 % मिलता है Difference: 0.00018957 ms / 73 % , इस प्रकार गेटप्पाटा / सेटपडेटा का उपयोग करके मुझे 73% का प्रदर्शन सुधार मिलता है! ध्यान दें कि यदि 10x10 डबल चर का उपयोग किया जाता है तो परिणाम नहीं बदलता है, हालांकि, यदि बड़े डेटा वाले कई फ़ील्ड्स handles होते हैं, तो परिणाम बदल जाएगा।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow