26 Januari 2012

GUI C++ Hello World Dengan wxWidgets

Untuk berkenalan dengan wxWidget, silahkan kunjungi http://en.wikipedia.org/wiki/WxWidgets atau http://id.wikipedia.org/wiki/WxWidgets. Pada post saya ini, saya akan langsung membahas praktik penggunaan dan pembahasannya. Program yang akan saya buat adalah program sangat sederhana untuk menampilkan window dengan titlebar bertuliskan "Hello World" dan dilengkapi dengan menubar dan statusbar. Post ini sebenarnya adalah terjemahan ke dalam bahasa Indonesia dari halaman http://www.wxwidgets.org/docs/tutorials/hello.htm

Untuk menggunakan wxWidgets, tentu saja anda harus meng-include header file dari wxWidgets. Anda bisa melakukannya dengan meng-include tiap file satu persatu (misalnya #include #wx/window.h") atau menggunakan global include (#include "wx/wx.h"). Langkah ini juga sangat berguna ketika anda menggunakan precompiled header.

#include "wx/wx.h"

Secara praktis, setiap aplikasi harus mendefinisikan class turunan dari class wxApp. Dengan meng-overriding method OnInit() milik class wxApp, program yang dibuat bisa diinisialisasikan, misalnya untuk membuat window utama baru.

class AplikasiSaya: public wxApp {
 virtual bool OnInit();
};

Window utama adalah sebuah class turunan dari wxFrame dan memberikan menu dan status bar pada saat konstruksi. Dan juga, jika ada class yang ingin merespond terhadap "event" (misalnya klik mouse atau message dari menu atau button) harus mendeklarasikan sebuah tabel event menggunakan macro seperti di bawah. Akhirnya, reaksi terhadap suatu event harus dilakukan dalam "handlers". Pada contoh ini. kita akan memberikan reaksi terhadap dua item menu, satu untuk "Quit" dan satu untuk menampilkan jendela "about". Handler-handler ini tidak boleh virtual.

class FrameSaya: public wxFrame {
 public:
  FrameSaya(const wxString& title, const wxPoint& pos, const wxSize& size);
  
  void OnQuit(wxCommandEvent& event);
  void OnAbout(wxCommandEvent& event);
  
  DECLARE_EVENT_TABLE();
};

Agar dapat bereaksi terhadap perintah menu, handler diberikan sebuah identifier yang unik seperti const atau enum.

enum { ID_Quit = 1,
    ID_About,
};

Proses selanjutnya adalah mengimplementasikan tabel event dimana masing-masing event diarahkan ke handler function masing-masing di dalam class FrameSaya. Terdapat macro yang sudah didefinisikan sebelumnya untuk mengarahkan event-event umum, cakupannya mulai dari pemilihan entry list box sampai event mengubah ukuran ketika user mengubah ukuran sebuah window pada layar.

BEGIN_EVENT_TABLE(FrameSaya, wxFrame)
 EVT_MENU(ID_Quit, FrameSaya::OnQuit)
 EVT_MENU(ID_About, FrameSaya::OnAbout)
END_EVENT_TABLE()

Sebagaimana di dalam semua program memiliki fungsi main. Pada wxWidgets, fungsi main diimplementasikan menggunakan macro dibawah ini, yang mana akan membuat sebuah instansi aplikasi dan memulai program.

IMPLEMENT_APP(AplikasiSaya)

Seperti yang sudah disebutkan sebelumnya, wxApp::OnInit() dipanggil saat startup dan seharusnya digunakan untuk inisialisasi program, mungkin menunjukan "splash screen" dan membuat jendela utama(atau yang lainnya). Satu frame juga bisa dideklarasikan sebagai jendela paling atas. Indikasi dari inisialisasi yang sukses adalah ketika mengembalikan TRUE.

bool AplikasiSaya::OnInit() {
 FrameSaya *frame = new FrameSaya( _("Hello World"), wxPoint(50,50), wxSize(450,340) );
 frame -> Show(true);
 SetTopWindow(frame);
 return true;
}

Pada konstruksi jendela utama, kita membuat sebuah menu dengan dua item menu beserta sebuah status bar yang akan ditampilkan di dasar jendela utama. Keduanya harus "diumumkan" kepada frame dengan pemanggilan masing-masing.

FrameSaya::FrameSaya(const wxString& title, const wxPoint& pos, const wxSize& size)
   : wxFrame(NULL, -1, title, pos, size)
{
 wxMenu *menuFile = new wxMenu;
 menuFile->Append(ID_About,_("&About...") );
 menuFile->AppendSeparator();
 menuFile->Append( ID_Quit, _("E&xit") );
 
 wxMenuBar *menuBar = new wxMenuBar;
 menuBar->Append( menuFile, _("&File") );
 
 SetMenuBar( menuBar );
 CreateStatusBar();
 SetStatusText( _("Welcome to WxWidget!") );
}

Berikut ini adalah event handler yang sebenarnya. FrameSaya::OnQuit() akan menutup jendela utama dengan memanggil fungsi Close(). Parameter TRUE mengindikasikan bahwa jendela lain tidak memiliki "veto power" seperti misalnya menanyakan "Do you realy want to quit?". Jika tidak ada jendela, lain lagi, aplikasi akan menutup.

void FrameSaya::OnQuit(wxCommandEvent& WXUNUSED(event)) {
 Close(true);
}

FrameSaya::OnAbout() akan menampilkan window kecil dengan beberapa teks di dalamnya. Dalam hal ini, window "about" umum dengan informasi mengenai program.

void FrameSaya::OnAbout(wxCommandEvent& WXUNUSED(event)) {
 wxMessageBox( _("This is a wxWidgets hello world sample"),
      _("About Hello World"),
      wxOK | wxICON_INFORMATION, this );
} 

Setelah selesai coding, simpan dalam file dengan nama hworld.cpp. Selanjutnya adalah kompilasi, perintah kompilasi adalah:
g++ hworld.cpp `wx-config --libs` `wx-config --cxxflags` -o hworld

Kemudian untuk eksekusi program, perintah yang digunakan seperti biasa, yaitu: ./hworld.

Berikut ini adalah coding lengkap dan screenshotnya:

#include "wx/wx.h"

class AplikasiSaya: public wxApp {
 virtual bool OnInit();
};

class FrameSaya: public wxFrame {
 public:
  FrameSaya(const wxString& title, const wxPoint& pos, const wxSize& size);
  
  void OnQuit(wxCommandEvent& event);
  void OnAbout(wxCommandEvent& event);
  
  DECLARE_EVENT_TABLE();
};

enum { ID_Quit = 1,
    ID_About,
};

BEGIN_EVENT_TABLE(FrameSaya, wxFrame)
 EVT_MENU(ID_Quit, FrameSaya::OnQuit)
 EVT_MENU(ID_About, FrameSaya::OnAbout)
END_EVENT_TABLE()

IMPLEMENT_APP(AplikasiSaya)

bool AplikasiSaya::OnInit() {
 FrameSaya *frame = new FrameSaya( _("Hello World"), wxPoint(50,50), wxSize(450,340) );
 frame -> Show(true);
 SetTopWindow(frame);
 return true;
}

FrameSaya::FrameSaya(const wxString& title, const wxPoint& pos, const wxSize& size)
   : wxFrame(NULL, -1, title, pos, size)
{
 wxMenu *menuFile = new wxMenu;
 menuFile->Append(ID_About,_("&About...") );
 menuFile->AppendSeparator();
 menuFile->Append( ID_Quit, _("E&xit") );
 
 wxMenuBar *menuBar = new wxMenuBar;
 menuBar->Append( menuFile, _("&File") );
 
 SetMenuBar( menuBar );
 CreateStatusBar();
 SetStatusText( _("Welcome to WxWidget!") );
}

void FrameSaya::OnQuit(wxCommandEvent& WXUNUSED(event)) {
 Close(true);
}

void FrameSaya::OnAbout(wxCommandEvent& WXUNUSED(event)) {
 wxMessageBox( _("This is a wxWidgets hello world sample"),
      _("About Hello World"),
      wxOK | wxICON_INFORMATION, this );
}



4 komentar:

  1. Mirip sekali dengan C++ yang dipaket dengan Qt. Apa saja kelebihan wxWidget itu, Kang? Terima kasih.

    BalasHapus
    Balasan
    1. Wah, sayang sekali saya menunda pembelajaran mengenai WxWidget ini. Jadi saya belum bisa menjawab pertanyaannya :)

      Hapus
    2. CMIIW, kelebihannya antara lain:
      - Of course cross platform development possible is most preferred .. Windows, Linux and Mac.
      - Trully OOP/C++
      - Class Library yang sangat lengkap, mulai dari class untuk GUI hingga non GUI, thread, network, file/system, stream .. etc.
      - UI control/window/widgets yang dihasilkan terlihat sangat native baik di windows, linux maupun mac.
      - License yang sangat flexible dibanding Qt, sehingga kita bisa menggunakan library dalam bentuk static maupun dynamic linking. Juga tidak tertutup kemungkinan untuk membuat program closed atau open source. Bandingkan dengan Qt yang (kalau tidak salah) mengharusnya program yang opensource jika kita tidak membeli development licensenya.
      - Dynamic library windows dll yang untuk deploy program aplikasi yang dibuat juga lebih kecil dari dll nya qt.

      Hapus
  2. Makasih bang buat bagi2 ilmunya. Saya juga sedang membangun software dengan wxWidgets ini. Main juga ke blog saya ya, mungkin kita bisa share ttg librari yang satu ini, tks

    BalasHapus