در پست قبلی در خصوص ساخت رابط گرافیکی کاربر در نرم افزار متلب این بار قصد داریم مثال های بیشتری در این زمینه مطرح سازیم. در این مقاله ما به ساخت یک جمع کننده ساده را میپردازیم. در این پروژه، مشابه پروژه قبلی ما از edit text ، static text و push button استفاده میکنیم. در مقاله قبلی ما به طور کامل در مورد چگونگی افزودن عناصر به صفحه GUI بحث کردیم و خواندن بخش اول را توصیه میکنیم. حال مثال جدید را شروع میکنیم و در ابتدا عبارت زیر را وارد میکنیم تا وارد محیط GUI شویم :
>> guide
باید مطابق شکل دو edit text و دو static text و یک push button را به صفحه اضافه کنیم. در واقع شیوه کار به گونه ای است که دو عدد در edit text ها وارد میشوند و دکمه ای برای عملیات ضرب در نظر گرفته میشود و با زدن این دکمه نتیجه در یک static text چاپ میشود.
حال تنظیمات tag و string را به صورت زیر برای عناصر انجام میدهیم (با دو بار کلیک بر روی هر عنصر به پنجره خصوصیات آن می توانیم دسترسی پیدا کنیم) :
و نتیجه به این صورت خواهد بود :
حال پنجره را با نام دلخواه (مثلا adder.fig) ذخیره میکنیم. قبلا از ایجاد کد ها برای این مثال باید به این نکته توجه کنیم که سه دستور مهم در هنگام کار با GUI وجود دارد : get , guiddata و set
دستور get یک داده رشته ای را از یک بخش ورودی دریافت میکند. برای مثال اگر بخواهیم عددی را که کاربر در باکس edit1 وارد میکند، دریافت کنیم، میتوانیم اینگونه عمل کنیم:
get(handles.edit1, 'String')
اما این دستور یک رشته متنی را میگیرد نه یک عدد. پس ابتدا باید داده ورودی را از رشته به عدد تبدیل نماییم :
num = str2double(get(handles.edit1,'String'));
در نهایت ما باید مقدار عنصر مورد نظر را به روز رسانی نماییم و متغیر را در حافظه ذخیره نماییم تا در تابع callback دیگر مورد استفاده قرار گیرد . که این کار با دستور guidata امکان پذیر است و داریم:
handles.edit1 = num; guidata(hObject,handles)
به طور کلی ، باید تمام توابع callback با این عبارت خاتمه پیدا کنند:
guidata(hObject,handles)
و این کار به منظور حفظ مقادیر متغیر ها در حافظه انجام میپذیرد.
در ادامه مبحث ساخت رابط گرافیکی کاربر در نرم افزار متلب ، همانطور که میدانید تابع set نیز برای تنظیم یک ویژیگی از عنصر خاص مورد استفاده قرار میگیرد. در این مثال میخواهیم با فشار دادن کلید + مقدار static text به مقدار حاصلجمع set شود. حال به سراغ نوشتن کد های مربوطه میرویم. مطابق قبل برای ساخت کدها بر روی edit1 راست کلیک میکنیم و سپس از گزینه view به قسمت callbacks و بعد callback میرویم و علاوه بر کدهای ساخته شده توسط خود نرم افزار، چند خظ کدنویسی میکنیم که در نهایت به این صورت خواهد بود:
function edit1_Callback(hObject, eventdata, handles) % hObject handle to edit1 (see GCBO) % eventdata reserved - to be defined in a future version of MLB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of edit1 as text % str2double(get(hObject,'String')) returns contents of % edit1 as a double num = str2double(get(hObject,'String')); if isnan(num) num = 0; set(hObject,'String',num); errordlg('Input must be a number', 'Error') end handles.edit1 = num; guidata(hObject,handles)
در این تابع، ما در ابتدا ورودی کاربر را با دستور get خوانده و همزمان آن را تبدیل به عدد میکنیم و در متغیر num قرار میدهیم. توضیحی که در اینجا وجود دارد این است که در اینجا عبارت (‘get(hObject,’String معادل (’get(handles.edit1,’String است.
نکته ای که در این کد نویسی وجود دارد این است که ما باید پک کنیم که حتما کاربر عدد وارد کرده باشد و متنی را به جای عدد در کادر ننوشته باشد. این کار را در اینجا با تابع isnan انجام میدهیم که مخفف IS Not A Number است و اگر num یک عدد نباشد یک خطا را لاگ میکند و مقدار num را هم برابر صفر قرار میدهد. در نهایت با دو خط پایانی مقدار ورودی را در حافظه ذخیره میکنیم.
برای edit2 نیز مطابق بالا عمل میکنیم و داریم :
function edit2_Callback(hObject, eventdata, handles) % hObject handle to edit2 (see GCBO) % eventdata reserved - to be defined in a future version of MLB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of edit2 as text % str2double(get(hObject,'String')) returns contents of % edit2 as a double num = str2double(get(hObject,'String')); if isnan(num) num = 0; set(hObject,'String',num); errordlg('Input must be a number', 'Error') end handles.edit2 = num; guidata(hObject,handles)
حال با استفاده از تابع guidata هر دو ورودی در متغیر های handles.edit1 و handles.edit2 ذخیره شده اند (به صورت عدد) . حال به سراغ تابع callback برای دکمه push-button میرویم و کدهایی را به آن می افزاییم :
% --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MLB % handles structure with handles and user data (see GUIDATA) addition = handles.edit1 + handles.edit2; set(handles.result, 'String', addition);
با تابع set و با ساختار بالا ، حاصلجمع دو متغیر ذخیره شده را به static text نسبت میدهیم که قبلا پارامتر tag آن را مطابق جدول برابر عبارت result قرار دادیم.
حال سوالی که مطرح است این است که اگر کابر بدون واردکردن هیچ ورودی بر روی دکمه + کلیک کند مشکلی پیش خواهد آمد؟ متأسفانه جواب مثبت است و در خروجی با خطا مواجه میشویم. در واقع ما خاصین string را برای edit1 وedit2 مقدار 0 قرار دادیم که به صورت رشته است و اگر بر روی edit text ها کلیک نکنیم ، عملیات تبدیل رشته به عدد انجام نمیشود. اما راه حل چیست؟ باید کدهایی را اضافه کنیم که قبل از adder اجرا شوند و این سه خط را در ینجا قرار دهید:
% --- Executes just before adder is made visible. function adder_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MLB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to adder (see VARARGIN) % Choose default command line output for adder handles.output = hObject; num = 0; handles.edit1 = num; handles.edit2 = num; % Update handles structure guidata(hObject, handles); % UIWAIT makes adder wait for user response (see UIRESUME) % uiwait(handles.figure1);
در مبحث رابط گرافیکی کاربر در نرم افزار متلب ،کار ساخت یک جمع کننده را انجام دادیم و باگ های موجود در آن را با هم رفع کردیم و در خروجی خواهیم داشت :
در این آموزش و در ادامه بخش اول، با عنوان ساخت رابط گرافیکی کاربر در نرم افزار متلب، با مفاهیم کار با GUI آشنا شدیم.