Cách trao đổi dữ liệu hiệu quả giữa các hàm Callback của GUI

Chào các bạn.

Một vấn đề mà các bạn hay gặp phải khi thực hiện lập trình giao diện GUI là trao đổi dữ liệu giữa các hàm Callback hay của chính hàm Callback đó. Ví dụ: bạn làm sao biết hàm Callback này chạy được bao nhiêu lần ?? Nếu bạn muốn thực hiện một điều gì đó khi hàm này chạy đến lần thứ 2 thì làm sao ?? Nếu muốn lấy kết quả của một hàm Callback khác thì làm sao ??

Giải pháp tất nhiên là phải ghi vào một nơi mà có thể truy suất bất kì lúc nào trong các hàm Callback.

Ngày xưa, lúc mới lập trình GUI mình có nghĩ đến dùng cách ghi dữ liệu cùa biến nhớ, data vào một file .mat rồi dùng các lệnh load, save để đọc và ghi vào file này. Tuy nhiên, vấn đề vớ vẩn hay gặp là khi bạn ghi liên tục khối dữ liệu lớn thì file này sẽ bị hỏng và báo rằng không đọc, ghi được. Bó tay luôn, hic hic.

Đọc đến cấu trúc handles thấy quả thật đây là giải pháp Pro nhất rồi. Không còn gặp trục trặc khi trao đổi dữ liệu nữa. Chi tiết xin các bạn xem tham khảo [1] rất là đầy đủ.

handles là một cấu trúc mà các trường của nó chính là các handle của các điều khiển trong GUIDE. Chúng ta vẫn dùng cấu trúc này để thiết lập các thuộc tính của các điều khiển trong GUI.

Thêm các trường vào cấu trúc Handles

Cấu trúc handles chính là tham số của tất cả các hàm Callback. Để thêm một trường vào trong cấu trúc handles chúng ta làm theo 2 bước sau:

  1. Gán một giá trị vào trường mới của handles. Ví dụ:
    handles.number_errors = 0;

    đã thêm trường number_errors vào cấu trúc handles và khởi tạo với giá trị 0. Chú ý: nên khởi tạo một trường mới của handles trong hàm OpenFcn của GUI để trường này luôn được tạo khi GUI chạy và khi đó tất cả các hàm Callback đều truy nhập được vào trường đã khởi tạo này.

  2. Dùng lệnh sau đây để lưu dữ liệu:
    guidata(hObject,handles)

    trong đó hObject là handles của thành phần mà đang gọi hàm callback. hObject là tham số luôn luôn có ở các hàm Callback, được tự động tạo bởi GUIDE.

Cập nhật GUI Data trong M-file tạo bởi GUIDE

Khi đã tạo ra một trường mới trong handles thì bây giờ chúng ta truy nhập và cập nhật giá trị của nó như thế nào ??

Ở bên trên chúng ta đã tạo ra một trường với tên là number_errors. Bây giờ chúng ta sẽ gán một giá trị khác cho nó và lưu dữ liệu vào. Tất nhiên phải làm theo như sau:

  1. Thay đổi giá trị của trường number_errors thành 10.
    handles.number_errors = 10;
  2. Lưu lại cấu trúc handles với lệnh sau:
    guidata(hObject,handles)

    trong đó hObject là biến của hàm Callback chính là handle của chính điều khiển gọi hàm Callback đó. Nếu bạn không ghi dữ liệu handles vào GUIDATA thì sẽ bị mất mà ngay. Nó sẽ vẫn lưu giá trị cũ thôi.

Lấy giá trị từ cấu trúc handles

Tất nhiên để lấy một giá trị từ một trường của handles, chúng ta làm như sau:

a = handles.number_errors;

Quá đơn giản phải không ke ke.

Xem thêm về GUIDATA tại tham khảo [2].

Các bạn có thể xem thêm về Application Data, tức là tạo một cấu trúc tương tự như handles. Cách này mở rộng hơn không nhất thiết phải cho các figure.

Tham khảo

[1] Mathwors Corp, Mechanisms for Managing Data

[2] Mathworks Corp, GUI Data

{ 27 comments… add one }
  • bqthanh June 24, 2008, 8:45 am

    em load được cái ảnh rùi, nhưng sao nó hiện luôn cả path của cái ảnh lên luôn vậy anh

    Reply
  • bqthanh June 25, 2008, 7:31 am

    xin lỗi anh, em hỏi lộn bên topic này. Em muốn xóa nhưng không biết cách xóa.Nên đành để vậy.Anh thông cảm lần sau em sẽ cẩn thận hơn.

    Reply
  • phap July 9, 2008, 1:33 am

    em đã đọc phần hướng dẫn của matlab “image processing” nhưng em vẫn không hiểu anh cho em hỏi vấn đề này nha! em cảm ơn anh trước
    [X,map]= imread(filename,fmt);
    anh co the nói rõ cho em biết là X và map la dử liệu gì lệnh trên dùng cho việc đọc loại ảnh nào.
    anh chỉ giúp em cách lấy giá trị của một màu trong một file ảnh được không? thank

    Reply
  • le tat thang April 16, 2009, 3:00 pm

    em muon tao mot nut back .o phan thuoc tinh em chon control-callback:chuonhtrinhchinh
    chu y:chuongtrinhchinh la chuong trinh em muon quay ve
    nhung khi quay ve figure.chuongtrinhchinh tho van ton tai figure cua chuong trinh cu .anh co the giup em giai quyet bai toan nay khong

    Reply
    • ngohaibac April 16, 2009, 10:31 pm

      Chào em.

      Cái đó không khó mấy đâu em. Điều em muốn có phải là muốn cho cái figure cũ tắt đi đúng không nào. Em có thể dùng lệnh:

      delete(hObject);

      Sau khi em gọi lệnh cho figure mới ra. Nhớ là lệnh gọi figure mới và delete nên cho vào trong hàm callback mặc định của nó thì hay hơn là config trong cửa sổ Property.

      Reply
  • tuthantuthuc January 22, 2010, 10:21 am

    Cám ơn admin rất nhiều cề những bài viết này. Hi vọng anh tiếp tục viết những bài hướng dẫn cụ thể và trực quan như vầy nữa để mọi người có thể tham khảo và học tập.
    Anh cho em hỏi dùng lệnh gọi một cái fig mới ra có fải là dùng lệnh call (fig.) ko anh? EM mới tìm hiểu về phần GUIDE này nên chưa rõ lắm mong anh chỉ giáo.

    Reply
  • cool boy February 4, 2010, 9:02 am

    các bạn cho mình hỏi có cách nào để đánh chữ tiếng việt có dấu trong gui ko?

    Reply
  • tran huy hoang March 11, 2010, 9:33 am

    minh muon hoi la matlap co tuong thich voi cac phan mem khac khong???. vi du nhu phan mem tao web chang han. Vi minh dang duoc giao nhiem vu lap chuong trinh tinh toan cac may ki thuat sau do phai show no len sao cho gioing mot trang web. ma minh chi moi viet duoc chuong trinh tinh don thuan trong matlap. bac nao biet hay noi qua cho em voi????. Em cam ơn!!!!!!

    Reply
  • tpk711 April 22, 2010, 3:24 pm

    Chào anh.
    Em muốn xuất ra cùng một edit text nhiều dữ liệu thì làm thế nào hả anh?
    Ví dụ như em muốn đưa ra dòng “đây là 1 đường tròn”, sau đó lại muốn đưa lên “bán kính là: r” trên cùng một edit text.

    Reply
    • ngohaibac April 22, 2010, 3:38 pm

      Em dùng hàm sprintf, gõ lệnh help sprintf. Hàm này là hàm chuẩn ở trong C đó, cú pháp tương tự.

      Ví dụ: sprintf(buf,”Đây là đường tròn, bán kính: %d”,r);

      Có thể ý của em là thêm dữ liệu vào string đó thì làm như sau:

      str = 'Day la duong tron';
      str = [str,' ban kinh r']

      Chúc em thành công.

      Reply
    • ngohaibac April 22, 2010, 3:40 pm

      Em dùng lệnh dạng như sau:

      str = 'Day la 1 duong tron';
      str = [str,' ban kinh r']

      Chúc em thành công.

      Reply
  • tpk711 April 23, 2010, 3:02 am

    chào anh.
    Em có dòng lệnh sau làm trong guide.
    set(handles.text10,’String’,’Day la 1 elip’);
    Em muốn đưa vào cái text10 ấy thêm: “bán trục lớn là num2str(a) và bán trục nhỏ là: num2str(b)”.
    thì làm thế nào hả anh.
    Mà sao em làm xong một bài guide khi gửi cho bạn em, nó copy 2 file .m và .fig vào trong mục work của matlab. Xong gõ lệnh gọi hàm ấy ra mà nó lại không chạy trong khi máy em chạy ngon. Nó hiện lỗi như là mình bấm đúp chuột vào file .fig chứ không gọi từ matlab. Sửa như thế nào hả anh?

    Reply
    • ngohaibac April 23, 2010, 8:46 pm

      1. Em dùng lệnh format string là sprintf, xem thêm help sprintf

      2. Em chạy lệnh guide trước, rồi browse đến file .fig đó.

      Chúc em thành công.

      Reply
  • Letrieubk3i May 20, 2010, 1:22 am

    Anh Bắc cho em hỏi là làm thế nào để xuất kết quả ra file .txt.Ví dụ chương trình gui calculate bây giờ em xuất kết quả ra 1file .txt thì như thế nào anh.Mong anh chỉ em.Cám ơn anh!

    Reply
    • ngohaibac May 21, 2010, 3:59 pm

      Em sử dụng các function kiểu như fprintf là được.

      Reply
  • Lê Quang Thành May 18, 2011, 9:24 pm

    anh Bắc cho em hỏi chút xíu em đang gặp khó khăn vấn đề này
    em đang lập trình GUI vẽ đồ thị với dữ liệu nhận được từ cổng RS232
    em cứ mổi khi nhận được một byte thì nó gọi một hàm callback của đối tượng serial,em đả thử nhiều cách nhưng cái hàm được gọi này không thể nào tương tác với môi trường GUI được,
    Gui không thể lấy dử liệu từ nó,và hàm callback này cũng không thể truy xuất đến các đối tượng của GUI
    em nghỉ chắn chắn phải có biện pháp,mong được anh giúp đở!!

    Reply
  • Bahung July 26, 2011, 2:22 pm

    Xin chào tất cả anh em!
    Thấy mọi người trao đổi sôi nổi và hay phết, mình mới học Matlap lỏm bỏm nên xin hỏi anh em tí:
    Mình có guide1 trong đó có edit, mình nhập dữ liệu, và mình muốn lấy dữ liệu này để tính toán trong guide 2 thì phải làm sao? Mình có tham khảo và mọi người bảo dùng lệnh save và load nhưng không biết, Pro nào giúp với
    Cảm ơn trước!

    Reply
    • Hiến October 22, 2014, 10:37 am

      Mình cũng đang mắc vấn đề này
      Anh em nào biết trả lời giúp mình với
      mail của mình: vanhiencompany221182@gmail.com

      Reply
  • Phat1510 January 2, 2012, 3:31 pm

    Em đang viết một chương trinh đơn giản trong gui để xử lí một ảnh, em đã load ảnh và cho hiện ra axes được rồi. Giờ làm sao để tiếp tục sử dụng ảnh đó cho callback kế tiếp, đó là một nút để xoay ảnh trái phải. Xin hướng dẫn cho em, cám ơn !

    Reply
  • giot nang April 24, 2012, 2:00 pm

    em chào anh,em đang đọc encoder bằng card CPI 1711 ,nhưng do nhiễu nên đô thị vẽ không mịn,em dùng fdatool để lọc nhiễu nhưng em chưa hiểu cách dùng cái đó lắm,anh giúp em nha

    Reply
    • ngohaibac May 31, 2012, 3:52 pm

      FDATool là lọc nhiễu, em cần phải biết lọc bằng phương pháp gì, tần số cắt, … thì mới sử dụng tool dc chứ.

      Reply
  • buiduongtx2th89 March 30, 2013, 5:45 pm

    chào anh em
    — e muốn Save một cái hình ảnh từ camera, khi nhấn nút chụp thì nó sẽ lưu hình ảnh đó lại thành một biến để sau đó mình có thể lấy hình đó xử lý tiếp, lưu hình đó thành đuôi .jpg

    Reply
  • Thanh April 23, 2013, 2:11 pm

    Chào anh!
    em đang học madlab có vấn đề này em tìm không ra nhờ anh giúp
    em có 10 số từ 1 đến 10 và em muốn gán tương ứng là a b c d e f g h i k. Khi chạy chương trình nó sẽ được hai cột một cột số và một cột chữ tương ứng.
    nhờ anh chỉ giúp em
    cảm ơn anh

    Reply
  • nganguyen October 9, 2013, 2:47 pm

    Chao anh!
    Em đang tập tành với GUI trong Matlab. Em có 1 form với 1 nút chọn ảnh. hiện lên axes
    và 1 nút để show histogram của ảnh .trong nút show histogram em code a=rgb2gray(A);
    figure,imhist(a); A: là ảnh ban đầu chọn hiện lên axes. nhưng nhấn khi em chọn ảnh xong nhấn nút show histogram thì báo lỗi này
    :??? Undefined function or variable ‘A’.

    Error in ==> demo>pushbutton4_Callback at 102
    a=rgb2gray(A);

    Error in ==> gui_mainfcn at 96
    feval(varargin{:});

    Error in ==> demo at 42
    gui_mainfcn(gui_State, varargin{:});

    Error in ==>
    @(hObject,eventdata)demo(‘pushbutton4_Callback’,hObject,eventdata,guidata(hObject))

    Reply
  • nam học hỏi December 6, 2014, 1:45 am

    Anh ơi hướng dẫn giúp em một số vấn đề bên dưới với ạ:
    1. Có một lệnh readxxx, sau khi chạy lệnh thì cửa sổ command hiện bảng thông tin về file xxx. Vấn đề là tạo hai nút Button: 1 nút (open file) là để bấm vào nó hiện thư mục để mình chọn file xxx; nút thứ 2 (readxxx) bấm vào sẽ hiện bảng thông tin về file xxx giống như khi nó hiện trên cửa sổ command vậy.
    2. Lệnh hiển thị hình ảnh, cũng giống như ở trên, cũng tạo ra hai nút bấm như vậy nhưng chỉ khác ở nút thứ 2, ở trên là bấm vào nút thứ 2 sẽ hiện ra thông tin file xxx, còn ở đây nó hiển thị ra đồ thị được tạo ra từ cái file xxx đó.
    3. Lệnh convernt and write file xxx, cũng tương tự nhứ trên, nhưng nút thứ hai ở đây có chức năng là chuyển đổi file xxx và tạo ra một file khác (ví dụ: input=wav, convernt (input)=mp3, write(mp3)=output).

    Vì còn chưa rành về matlab nên ngôn từ nói theo kiểu nôm na để dễ trình bày mong anh thông cảm!
    Rất mong đươc sự trợ giúp của anh trong thời gian ngắn nhất vì em đang rất rất cần ngay ạ!
    Em cảm ơn anh rất nhiều!

    Reply
  • Bí ẩn April 8, 2015, 11:47 pm

    Có ai giỏi matlab ở hcm không? Cho em bái sư học với. Đang làm đồ án mà không biết sao code nó không chạy. Em làm truyền hình số mặt đất dbv-t.

    Reply

Leave a Comment