GUI programatik

Membangun antarmuka dengan uifigure dan komponen programatik sebagai dasar pemahaman GUI.

Daftar isi

GUI dapat dibangun tanpa editor visual karena MATLAB menyediakan fungsi pembentuk jendela dan komponen yang dipanggil langsung dari kode. Topik ini membahas pembangunan antarmuka programatik dengan uifigure, uibutton, uieditfield, dan uilabel beserta properti dan callbacknya. Pembahasan juga mencakup model komponen sebagai objek yang diakses lewat handle serta sejarah singkat dari figure ke uifigure. Karena lingkungan verifikasi jalur ini tidak menyediakan komponen uifigure, blok antarmuka ditampilkan tanpa dieksekusi. Inti yang berjalan nyata adalah fungsi validasi masukan yang dipakai callback untuk memeriksa teks kolom isian.

Jendela dan komponen sebagai objek#

uifigure adalah fungsi yang membuat jendela aplikasi generasi baru berbasis komponen web. Setiap komponen dibuat oleh fungsinya sendiri, yaitu uibutton untuk tombol, uieditfield untuk kolom isian, dan uilabel untuk teks statis. Setiap pemanggilan mengembalikan handle, yaitu rujukan objek komponen yang dapat disimpan pada variabel. Menyimpan seluruh handle pada satu struktur bernama h menjadikan antarmuka satu unit yang mudah dioper ke fungsi lain. Properti komponen diakses dengan tanda titik, misalnya h.Tombol.Text untuk teks tombol, dan penugasan nilai ke properti itu langsung mengubah komponen yang sedang berjalan.

Properti Position menempatkan komponen dengan empat bilangan, yaitu posisi x, posisi y, lebar, dan tinggi dalam piksel, dengan titik asal di pojok kiri bawah jendela. Properti Text mengatur tulisan pada tombol dan label, sedangkan Value memuat isi kolom isian yang berupa teks pada tipe text. Kode berikut menyusun jendela kalkulator dua operan secara penuh dari fungsi-fungsi tersebut.

matlab Jendela kalkulator dari komponen programatik
% tidak-dijalankan
h.Jendela = uifigure('Name', 'Kalkulator dua operan', ...
                     'Position', [100 100 340 260]);

h.LabelA = uilabel(h.Jendela);
h.LabelA.Text = 'Bilangan pertama';
h.LabelA.Position = [40 210 130 22];

h.BilanganA = uieditfield(h.Jendela, 'text');
h.BilanganA.Position = [180 210 120 24];
h.BilanganA.Value = '12';

h.LabelB = uilabel(h.Jendela);
h.LabelB.Text = 'Bilangan kedua';
h.LabelB.Position = [40 175 130 22];

h.BilanganB = uieditfield(h.Jendela, 'text');
h.BilanganB.Position = [180 175 120 24];
h.BilanganB.Value = '4';

h.Tombol = uibutton(h.Jendela, 'push');
h.Tombol.Text = 'Jumlahkan';
h.Tombol.Position = [180 140 120 26];

h.LabelHasil = uilabel(h.Jendela);
h.LabelHasil.Text = 'hasil tampil di sini';
h.LabelHasil.Position = [40 90 260 22];

Setiap komponen dibuat dengan jendelanya sebagai argumen pertama sehingga komponen menjadi anak dari h.Jendela. Urutan pembuatan bebas, tetapi urutan penugasan Position menentukan tata letak akhir. Model pemrograman ini berorientasi objek penuh: tidak ada pemanggilan gambar manual, dan keadaan antarmuka sepenuhnya terbaca dari properti objeknya.

Callback sebagai fungsi peristiwa#

Callback adalah fungsi yang dijalankan ketika sebuah peristiwa terjadi pada komponen, dan peristiwa tombol dikenali lewat properti ButtonPushedFcn. Properti ini diisi handle fungsi yang menerima dua argumen, yaitu sumber berupa objek komponen pemicu dan peristiwa berupa data kejadiannya. Kedua argumen selalu hadir meskipun isinya tidak selalu dipakai, karena pemanggilan callback mengikuti bentuk yang seragam untuk semua komponen.

matlab Callback penekanan tombol Jumlahkan
% tidak-dijalankan
h.Tombol.ButtonPushedFcn = @(sumber, peristiwa) ...
    tombol_ditekan(sumber, peristiwa, h);

function tombol_ditekan(sumber, peristiwa, h)
  fprintf('tombol %s ditekan\n', sumber.Text);
  status_a = validasi_masukan(h.BilanganA.Value);
  status_b = validasi_masukan(h.BilanganB.Value);
  if ~status_a.sah
    h.LabelHasil.Text = status_a.pesan;
  elseif ~status_b.sah
    h.LabelHasil.Text = status_b.pesan;
  else
    h.LabelHasil.Text = sprintf('%g tambah %g = %g', ...
        status_a.nilai, status_b.nilai, ...
        status_a.nilai + status_b.nilai);
  end
end

Handle @(sumber, peristiwa) tombol_ditekan(sumber, peristiwa, h) menangkap struktur h saat handle itu dibuat. Salinan tersebut tetap menunjuk komponen yang sama karena h berisi handle objek, sehingga perubahan dari dalam callback sampai ke antarmuka yang sedang berjalan. Argumen sumber dipakai untuk membaca Text tombol pemicu, sedangkan peristiwa tidak dipakai pada kasus ini dan dapat digantikan tanda ~. Validasi masukan dikerjakan fungsi terpisah agar callback tetap tipis dan aturannya teruji tanpa antarmuka.

Dari figure ke uifigure#

Selama lebih dari dua dekade antarmuka MATLAB dibangun dengan fungsi figure sebagai jendela dan uicontrol sebagai komponennya, sementara GUIDE menyediakan editor tarik-lepas di atas keduanya. Rilis R2016a memperkenalkan uifigure bersama App Designer, dan sejak itu MathWorks mengembangkan generasi baru secara aktif sambil menandai GUIDE sebagai fitur usang. Perbedaan kedua generasi komponen tersebut ringkas namun mendasar.

Aspekfigure dengan uicontroluifigure dengan uibutton
Komponensatu fungsi uicontrol untuk semua jenissatu fungsi per jenis seperti uibutton dan uieditfield
Penggambaranwidget bawaan sistem operasikomponen web yang dirender seragam lintas platform
Editor visualGUIDEApp Designer
Statusditandai usangdikembangkan aktif

Aplikasi yang dibuat App Designer sebenarnya adalah kode programatik uifigure yang dihasilkan editor, lengkap dengan struktur h dan seluruh callback-nya. Memahami pembangunan programatik karenanya berarti memahami isi berkas .mlapp yang dihasilkan, sehingga hasil kerja editor visual tetap dapat dibaca, disunting, dan diperluas secara manual. Model komponen web juga membuat tampilan antarmuka konsisten di Windows, macOS, dan Linux tanpa penyesuaian per platform.

Validasi masukan sebagai inti yang dapat diuji#

Kolom isian bertipe text memberikan nilai berupa teks, dan teks itu harus diubah menjadi bilangan sebelum dihitung. Fungsi str2double mengerjakan pengubahan itu, tetapi perilakunya terhadap teks yang gagal perlu diamati lebih dahulu karena menentukan rancangan validasi.

matlab str2double pada teks yang sah dan yang gagal
str2double('12.5')
str2double('')
str2double('dua')
text Keluaran
ans = 12.500
ans = NaN
ans = NaN

Teks yang sah menjadi bilangan, sedangkan teks kosong maupun teks yang bukan angka menjadi NaN tanpa error apa pun. Nilai NaN yang dibiarkan mengalir akan menjalar ke seluruh hasil perhitungan, sehingga pemeriksaan masukan menjadi bagian wajib aplikasi. Pemeriksaan itu ditulis sebagai fungsi terpisah berikut.

matlab validasi_masukan.m
function status = validasi_masukan(teks)
% VALIDASI_MASUKAN memeriksa teks masukan sebagai bilangan.
%   status = VALIDASI_MASUKAN(teks) mengembalikan struktur berbidang
%   sah, nilai, dan pesan. Bidang sah bernilai true hanya bila teks
%   terbaca sebagai bilangan hingga yang terdefinisi.
%   Tanpa argumen, contoh '37.5' dipakai.

if nargin < 1
  teks = '37.5';
end

nilai = str2double(teks);

if isnan(nilai)
  status.sah = false;
  status.nilai = NaN;
  status.pesan = 'teks tidak terbaca sebagai bilangan';
elseif ~isfinite(nilai)
  status.sah = false;
  status.nilai = nilai;
  status.pesan = 'nilai tidak berhingga';
else
  status.sah = true;
  status.nilai = nilai;
  status.pesan = 'masukan sah';
end
end

Fungsi ini mengembalikan struktur berbidang sah, nilai, dan pesan alih-alih sekadar bilangan atau error. Bidang sah memutuskan boleh tidaknya perhitungan berlanjut, bidang nilai membawa angka yang siap dipakai, dan bidang pesan sudah berbentuk teks sehingga langsung tertulis ke label hasil. Pemeriksaan isfinite menolak pula teks seperti Inf yang terbaca sebagai bilangan tetapi tidak berhingga. Empat contoh masukan diperiksa sebagai berikut.

matlab Memeriksa empat contoh teks masukan
contoh = {'12.5', '', 'dua', 'Inf'};
for i = 1:numel(contoh)
  status = validasi_masukan(contoh{i});
  if isempty(contoh{i})
    tampil = '(teks kosong)';
  else
    tampil = contoh{i};
  end
  fprintf('%-14s sah=%d nilai=%g pesan=%s\n', ...
          tampil, status.sah, status.nilai, status.pesan);
end
text Keluaran
12.5           sah=1 nilai=12.5 pesan=masukan sah
(teks kosong)  sah=0 nilai=NaN pesan=teks tidak terbaca sebagai bilangan
dua            sah=0 nilai=NaN pesan=teks tidak terbaca sebagai bilangan
Inf            sah=0 nilai=Inf pesan=nilai tidak berhingga

Hanya teks pertama yang lolos pemeriksaan, dan tiga teks lainnya ditolak dengan pesan yang berbeda sesuai penyebabnya. Callback pada bagian sebelumnya memakai struktur ini tanpa mengubah apa pun, karena keputusan boleh atau tidaknya menghitung sudah diambil fungsi validasi.

Kesalahan umum#

  • Membiarkan NaN mengalir dari str2double. Penyebabnya adalah konversi gagal secara diam-diam tanpa error. Akibatnya, seluruh hasil perhitungan menjadi NaN tanpa pesan yang menjelaskan kolom isian mana yang salah. Perbaikannya adalah memanggil fungsi validasi sebelum menghitung dan menghentikan cabang perhitungan bila status.sah bernilai false.
  • Menulis validasi hanya di dalam callback. Penyebabnya adalah kebiasaan melengkapi callback begitu antarmuka jadi. Akibatnya, aturan validasi tidak dapat diuji tanpa menjalankan aplikasi. Perbaikannya adalah menaruh aturan pada fungsi biasa seperti validasi_masukan lalu memanggilnya dari callback.
  • Mencampur komponen lama dengan jendela baru. Penyebabnya adalah contoh era figure dan uicontrol dipakai pada jendela uifigure. Akibatnya, komponen tidak tampil atau pemanggilannya error karena generasi komponen tidak boleh tercampur. Perbaikannya adalah memakai uibutton, uieditfield, dan uilabel untuk seluruh komponen di jendela uifigure.

Ringkasan#

  • Antarmuka programatik dibangun dari uifigure sebagai jendela serta uibutton, uieditfield, dan uilabel sebagai komponen, dan setiap komponen diakses lewat handle yang disimpan pada struktur h.
  • Properti utama meliputi Position dengan titik asal di pojok kiri bawah, Text untuk tulisan, dan Value untuk isi kolom isian bertipe text berupa teks.
  • Callback dipasang pada properti ButtonPushedFcn sebagai handle fungsi dengan argumen sumber dan peristiwa, dan struktur h yang ditangkap tetap menunjuk komponen yang sama.
  • Validasi masukan ditulis sebagai fungsi terpisah validasi_masukan yang mengembalikan struktur berbidang sah, nilai, dan pesan, sehingga aturannya teruji tanpa antarmuka.

Referensi#