2008-11-07 8 views
5

क्या किसी फ़ंक्शन के अंदर से GUI लिखना संभव है?MATLAB में किसी फ़ंक्शन के अंदर GUI कैसे बनाएं?

समस्या यह है कि सभी जीयूआई कार्यों का कॉलबैक वैश्विक कार्यक्षेत्र में मूल्यांकन किया जाता है। लेकिन कार्यों का अपना कार्यक्षेत्र होता है और वैश्विक कार्यक्षेत्र में चर का उपयोग नहीं कर सकता है। क्या GUI- फ़ंक्शन फ़ंक्शन के वर्कस्पेस का उपयोग करना संभव है? उदाहरण के लिए:

function myvar = myfunc() 
    myvar = true; 
    h_fig = figure; 

    % create a useless button 
    uicontrol(h_fig, 'style', 'pushbutton', ... 
         'string', 'clickme', ... 
         'callback', 'myvar = false'); 

    % wait for the button to be pressed 
    while myvar 
     pause(0.2); 
    end 

    close(h_fig); 

    disp('this will never be displayed'); 
end 

इस घटना को लूप, अनिश्चित काल तक चलने के बाद से कॉलबैक फ़ंक्शन में myvar में बदलाव नहीं करेगी होगा। इसके बजाय यह वैश्विक कार्यक्षेत्र में एक नया myvar तैयार करेगा।

उत्तर

5

build a GUI के लिए कई तरीके हैं, जैसे कि ऐप डिज़ाइनर, मार्गदर्शिका या प्रोग्रामेटिक रूप से इसे बनाने के कई तरीके हैं (मैं नीचे इस विकल्प को चित्रित करूंगा)। अपने जीयूआई घटकों और options available for sharing data between components के लिए different ways to define callback functions से अवगत होना भी महत्वपूर्ण है।

जिस दृष्टिकोण का मैं आंशिक हूं, वह कॉलबैक के रूप में nested functions का उपयोग कर रहा है। यहाँ एक उदाहरण के रूप में एक सरल GUI है:

function make_useless_button() 

    % Initialize variables and graphics: 
    iCounter = 0; 
    hFigure = figure; 
    hButton = uicontrol('Style', 'pushbutton', 'Parent', hFigure, ... 
         'String', 'Blah', 'Callback', @increment); 

    % Nested callback function: 
    function increment(~, ~) 
    iCounter = iCounter+1; 
    disp(iCounter); 
    end 

end 

जब आप इस कोड को चलाने के लिए, काउंटर प्रदर्शित किया एक एक करके हर बार जब आप बटन दबाएँ को बढ़ा देते चाहिए, नेस्टेड समारोह incrementmake_useless_button के कार्यक्षेत्र की पहुंच है और इस प्रकार कर सकते हैं क्योंकि iCounter संशोधित करें। ध्यान दें कि बटन कॉलबैक function handle पर increment पर सेट किया गया है, और यह फ़ंक्शन डिफ़ॉल्ट रूप से दो तर्क स्वीकार करना होगा: यूआई घटक के लिए एक ग्राफिक्स हैंडल जो कॉलबैक ट्रिगर करता है, और संबंधित ईवेंट डेटा की संरचना। हम इस मामले में ignore them with the ~ हैं क्योंकि हम उनका उपयोग नहीं कर रहे हैं।

अपने विशेष समस्या के लिए ऊपर दृष्टिकोण का विस्तार, आप अपने पाश जोड़ सकते हैं और कॉलबैक बदल तो यह गलत पर अपना ध्वज चर सेट कर सकते हैं:

function make_stop_button() 

    % Initialize variables and graphics: 
    keepLooping = true; 
    hFigure = figure; 
    hButton = uicontrol('Style', 'pushbutton', 'Parent', hFigure, ... 
         'String', 'Stop', 'Callback', @stop_fcn); 

    % Keep looping until the button is pressed: 
    while keepLooping, 
    drawnow; 
    end 

    % Delete the figure: 
    delete(hFigure); 

    % Nested callback function: 
    function stop_fcn(~, ~) 
    keepLooping = false; 
    end 

end 

drawnow यहाँ की जरूरत है बटन कॉलबैक एक मौका देने का लूप के भीतर प्रोग्राम प्रवाह को बाधित करने और keepLooping के मान को संशोधित करने के लिए।

1

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

अपने कोड में ऊपर है कि आप अपने इनलाइन कॉलबैक अर्थात करने के लिए अपने प्रारंभिक घोषणा करने के लिए वैश्विक कीवर्ड जोड़ने के लिए है और यह भी 'वैश्विक myVar = false'

+0

ओपी को आउटपुट वैरिएबल को किसी और चीज़ में बदलने की आवश्यकता होगी और इसके लिए काम करने के लिए बेस वर्कस्पेस में "ग्लोबल मायवर" बनाना होगा। – Azim

+0

क्या यह वास्तव में एकमात्र तरीका है? यह नौकरी के लिए वैश्विक वैरिएल्स का उपयोग करने के लिए तरह का झटका लगता है। – bastibe

+0

यह सबसे अच्छा तरीका है जिसके साथ मैं आया हूं - मैं मानता हूं कि यह थोड़ा बदसूरत है, मुझे नहीं लगता कि मैटलैब जीयूआई मॉडल बहुत अच्छा है। आप गणित पर उपयोग योग्य (?) योगदान में कोड को देखना चाह सकते हैं। साइट मिनट में नीचे है। –

1

मैं समस्या का समाधान मिल गया हो सकता है। कॉलबैक-फ़ंक्शन को जीयूआई की हैंडल-संरचना को संशोधित करना है।

function myfunc() 
    h_fig = figure; 

    % add continue_loop to the GUI-handles structure 
    fig_handles = guihandles(h_fig); 
    fig_handles.continue_loop = true; 
    guidata(h_fig, fig_handles); 

    % create a useless button 
    uicontrol(h_fig, 'style', 'pushbutton', ... 
         'string', 'clickme', ... 
         'callback', @gui_callback); 

    % wait for the button to be pressed 
    while fig_handles.continue_loop 
     fig_handles = guidata(h_fig); % update handles 
     pause(0.2); 
    end 

    close(h_fig); 
    disp('callback ran successfully'); 
end 

% The arguments are the Matlab-defaults for GUI-callbacks. 
function gui_callback(hObject, eventdata, handles) 
    % modify and save handles-Structure 
    handles.continue_loop = false; 
    guidata(hObject, handles); 
end 

टिप्पणी के बाद से, जबकि लूप केवल जब यह चलाया जाता है fig_handles अपडेट करेगा, आप हमेशा होगा: यह संरचना दोनों वैश्विक कार्यक्षेत्र के लिए नए चर शुरू करने के बिना कॉलबैक के भीतर से और समारोह से पहुँचा जा सकता कम से कम 0.2 सेकंड तक देरी हो जाती है जब तक लूप fig_handles.continue_loop

+0

आपके द्वारा यहां दिया गया उत्तर निश्चित रूप से सही दिखता है, और यह है कि कितने लोग शायद इस तरह की समस्या को संभालते हैं। यह व्यक्तिगत वरीयता के बारे में है: कुछ लोग गाइड का उपयोग करना पसंद करते हैं, जबकि मुझे हमेशा लगा कि मैं चीजों को नेस्टेड फ़ंक्शंस के साथ क्लीनर बना सकता हूं (हालांकि यह थोड़ा और काम है)। – gnovice

+0

मैं दूसरा हूं। असल में मुझे गाइड-जेनरेट कोड से बहुत पीड़ा मिली, मैंने fig2cmd लिखा - एक .fig फ़ाइल से निकालने के लिए इसे एक एम-फाइल में पुन: पेश करने के लिए जरूरी आदेश। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^