Trang 1 trên tổng số 4 123... Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 32 kết quả

Đề tài: Chuyên đề C++ | Lập trình GUI với gtkmm toolkit

  1. #1
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Mặc định Chuyên đề C++ | Lập trình GUI với gtkmm toolkit

    Gtkmm là 1 dạng toolkit dành cho lập trình GUI (graphic user interface) dành đặc biệt riêng cho Linux và Unix, nó cũng tượng tự như MFC của Microsoft, tuy nhiên đã là dân open-source T_T ai lại thèm chơi với tụi Micro làm gì phải không nào, chơi đồ free mới thích chứ hì hì T_T.
    I. Giới thiệu chung :
    -gtkmm là "C++ Interfaces for GTK+ and GNOME". (ngắn gọn dễ hiểu T_T )
    II. Làm sao để cài đặt :

    -Dễ hơn nữa T_T, ở đây tùy theo người nào dùng Fedora, hay Debian, hay gì gì đó thì cứ google :
    Code:
     gtkmm package for "OS của mình"
    -Ở đây do mình xài Ubuntu (dễ xài nhất), nên mình sẽ chỉ cách cài đặt cho Ubuntu.
    - Mở terminal lên type :
    Code:
    sudo apt-get install build-essential libglademm-2.4-dev libglibmm-2.4-dev libgtkmm-2.4-dev autoconf automake
    Xong type password admin của mình vào chờ đời và hồi hộp. Xong T_T, còn gì đơn giản hơn.
    Ở đây mình giả sử các bạn đã có sẵn g++ và gcc cài đặt trong máy, và có sẵn 1 text editor nào đó (emacs, kdevelop) rùi nhé. Nếu thực sự không biết 1 chút gì cũng chẳng sao ( post hỏi nhất định mình sẽ chỉ từ A->Z).
    III. Bạn cần biết gì để học gtkmm :
    - Tất nhiên nó là lập trình GUI nên không thể cho newbie được rùi T_T, nó không khó nhưng đòi hỏi bạn phải có 1 số kĩ năng sau đây :
    + Lập trình hướng đối tượng cơ bản với C++.
    + Cấu trúc dữ liệu (stack, queue, link list...)
    + Nắm vững các kĩ thuật con trỏ ( không cần expert ).
    + STL ( nếu rành nó + gtkmm thì tuyệt vời, không biết thì cũng không sao ).
    IV. Chương trình đầu tiên :
    Chỉ cần 5 dòng lệnh ta có ngay 1 chương trình GUI đúng nghĩa made in C++ ^_^.
    C++ Code:
    1. #include <gtkmm.h>
    2.  
    3. int main(int argc, char *argv[]){
    4.   Gtk::Main kit(argc, argv);
    5.   Gtk::Window window;
    6.   Gtk::Main::run(window);
    7.   return 0;
    8. }

    Copy paste save lại 1 cái tên nào đó ví dụ Ex1.cpp
    Mở terminal lên :
    Code:
     cd /home/...địa chỉ lưu file
    và dùng lệnh sau để dịch cho tất cả các chuơng trình gtkmm sau này :
    Code:
     g++ Ex1.cpp -o Ex1 -Wall -O3 -ansi -pedantic `pkg-config gtkmm-2.4 --cflags --libs`
    Lưu ý :
    - -Wall , -O3, -ansi, -pedantic là các flags của của compiler g++, gcc, nó hoàn toàn không liên quan gì đến gtkmm. Chúng ta cứ dùng y chang là được.
    - File name có tên Ex1 và cách ra bởi -o , và Ex1 là file executable.
    - Còn lại `pkg-config gtkmm-2.4 --cflags --libs` đây chính là phần để dịch được 1 chuơng trình gtkmm.

    Phân tích đoạn code đầu tiên của chúng ta :
    C++ Code:
    1. Gtk::Main kit(argc, argv);
    dòng này là bắt buộc đối với mọi chuơng trình gtkmm của chúng ta, nó tạo ra 1 đối tượng Gtk::Main có tên là kit nhận 2 đối mặc định argc và argv. Chúng ta cũng không cần quan tâm nhiều đến chúng làm gì.
    C++ Code:
    1. Gtk::Window window;
    Dòng này khởi tạo 1 đối tượng Gtk::Window có tên là window, và nó chính là cửa số mà chúng ta cần.
    C++ Code:
    1. Gtk::Main::run(window);
    Dòng này bắt đầu chạy cửa số đó cho tới khi chúng ta close nó ở dấu x hoặc Atl-F4.
    Vậy là chúng ta có 1 chuơng trình gtkmm đầu tiên rùi T_T, quá dễ, quá đơn giản phải không T_T.
    Và cái cửa sổ yêu dấu nhỏ xinh của chúng ta có hình dạng như thế này nè

    ...(còn tiếp)
    - Lưu ý tất cả các bạn có thể thoải mái đặt câu hỏi thoải mái về gtkmm, mình cũng chỉ đang học nên không dám nói là expert gì nhưng nếu chúng ta cũng thảo luận thì cả 2 cùng được học đúng không nào . Cho nên cứ hỏi và hỏi thật nhiều, có tài liệu gì hay thì chúng ta cùng chia sẻ với nhau.
    - Post tutorial cũng được.
    - Post tài liệu.
    - Post video.
    - Post câu hỏi.
    - Post code...
    Tất cả đều trong topic này, sau khi topic có 1 tí chất lượng thì mình sẽ sắp xếp lại cho nó ngăn nắp, nên các bạn không có gì phải ngại, cứ thoải mái mà hỏi và học !
    Và đây là tutorial hướng dẫn các bạn xài gtkmm on Window (Visual C++ 2005 )
    Đã được chỉnh sửa lần cuối bởi rox_rook : 06-04-2008 lúc 10:12 AM.

  2. #2
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Hi T_T, hôm nay chúng ta sẽ qua 1 bài khác là in ra cửa sổ có chữ Hello Word và các bạn sẽ thấy nó dễ như kẹo vậy .
    Chúng ta hãy bắt đầu với 1 số khái niệm cơ bản và hàm trong gtkmm :
    I. Signal
    - gtkmm nó cũng như mọi GUI toolkit khác, cũng là event-driven. Nghĩa là khi 1 sự kiện được xảy ra như ta click chuột, hay ấn phím thì tín hiệu sẽ được phát ra bởi 1 Widget. Và mỗi Widget sẽ có nhiều signal khác nhau. Và để tạo ra 1 hiệu quả ấn nút ta sẽ dùng 1 signal-handler để catch các tín hiệu này.
    Và gtkmm nó sử dụng thư viện libsigc++ để thực hiện các tín hiệu. Ví dụ chúng ta có 1 nút tín hiệu click được send vào bởi hàm ( singnal handler ) gọi là click_button_please.
    C++ Code:
    1. m_button.signal_clicked().connect( sigc::mem_fun(*this,
    2.   &HelloWord::click_button_please) );
    Ở đây :
    - HelloWord là 1 class chúng ta định nghĩa.
    - click_button_please() là hàm thành viên của nó dùng để xử lý tính hiệu.
    - m_button là 1 nút của lớp HelloWord, nó có dạng Gtk::Button m_button.
    - connect chỉ là syntax mặc định của gtkmm dùng để nhận tín hiệu mà thôi.
    - hàm signal_clicked() cũng vậy, là của gtkmm nên chúng ta không cần lo lắng làm gì lúc này.
    - còn mem_fun là 1 dạng function object quen thuộc của STL. Nếu chúng ta chưa biết về nó, ok, take a quick tour :
    ..
    Xem ví dụ sau :
    C++ Code:
    1. #include <iostream>
    2.    #include <vector>
    3.  
    4.    using namespace std;
    5.  
    6.    class Element {
    7.    public:
    8.      void print() { cout << "Element's print function\n";}
    9.    };
    10.  
    11.    int main() {
    12.      Element e1,e2,e3;
    13.      vector<Element*> E;
    14.      E.push_back(&e1);
    15.      E.push_back(&e2);
    16.      E.push_back(&e3);
    17.  
    18.      for (int j=0;j<E.size();j++)
    19.          E[j]->print();
    20.    }
    Quá quen thuộc phải không T_T, giả sử print() là 1 hàm thành viên như thế, và ta có 1 con trỏ Element* dùng để gọi các đối tượng e1, e2, e3...lúc run time. Khi gọi print() ta dùng E[j]->print(). Nhưng khi dùng container thì truy xuất trực tiếp như thế giảm performance về rất nhiều mặc -> lỗi out of bound. Vì vậy trong các container của STL nó mới nảy sinh ra các iterator. Bây h chúng ta có thể viết gọn là 1 dòng dùng STL xem sao :
    C++ Code:
    1. vector<Element*>::iterator;
    2. for (vector<Element*>::iterator i=E.begin();i<E.end();i++)
    3.          (*i)->print();
    Nhìn, OMG, code đọc vào muốn ngất ngư, sao mà phức tạp thế T_T. Đơn giản hơn tí nữa xem nào
    C++ Code:
    1. for_each (E.begin(),E.end(), &Element::print);
    for_each nhận 2 con trỏ đầu và đuôi + 1 function object print. Nhưng khoang, for_each nhận 1 global fucntion chứ không được là hàm thành viên :(. Vậy compiler nó sẽ complain. Và chúng ta sẽ nghĩ đến 1 giải pháp là :
    C++ Code:
    1. void do_print(Element *e) {
    2.          e->print();
    3.      }
    4.      ...
    5.      for_each (E.begin(),E.end(), do_print);
    Nhưng code này thật sự là quá không mấy hiệu quả, khi giả sử chúng ta có nhiều global function như vậy. Vậy thì mem_fun của STL sẽ là giải pháp tuyệt vời :
    C++ Code:
    1.  for_each (E.begin(),E.end(), mem_fun(&Element::print));
    1 dòng là, xong T_T, mem_fun nhận 1 con trỏ tới hàm thành viên, nhìn cú pháp thì quái chiêu thế nhưng đặt mắt vào nhìn chừng 2 phút là ok ngay .
    Một ví dụ nữa cho quen luôn nhé :
    C++ Code:
    1. #include <iostream>
    2. #include <vector>
    3. #include <functional>
    4.  
    5. using namespace std;
    6.  
    7. class Shape {
    8. public:
    9.   virtual void draw(){cout << "Drawing a shape\n"; };
    10. };
    11.  
    12.  
    13. class Triangle : public Shape {
    14.   void draw() {cout << "Drawing a triangle\n"; }
    15. };
    16.  
    17. class Square : public Shape {
    18.   void draw() {cout << "Drawing a square\n"; }
    19. };
    20.  
    21. int main() {
    22.   vector<Shape*> shapes;
    23.   Triangle t1,t2;
    24.   Square s1, s2;
    25.   shapes.push_back(&t1);
    26.   shapes.push_back(&s1);
    27.   shapes.push_back(&t2);
    28.   shapes.push_back(&s2);
    29.  
    30.   for_each( shapes.begin(),  shapes.end(), mem_fun(&Shape::draw));
    31. }
    Vậy là chúng ta đã hiểu hầu hết các chức năng trong 1 hàm rất thường dùng trong gtkmm. Let's move on T_T.

    II. HelloWord program :
    Và quả thật khi học gtkmm bạn sẽ có cảm giác bạn đang thực sự học C++, nó không như những toolkit khác, nó không sinh code làm cho bạn không thể nào hiểu nổi nó từ đâu ra mà chỉ ngậm ngùi chấm nhận. Học gtkmm bạn càng cảm thấy thích C++ hơn bao h hết .
    Xem ví dụ sau nào :
    C++ Code:
    1. #include <gtkmm/button.h>
    2. #include <gtkmm/window.h>
    3. #include <gtkmm/main.h>
    4. #include <iostream>
    5.  
    6. class print_hello : public Gtk::Window{
    7. public :
    8.   print_hello();
    9.   virtual ~print_hello();
    10. protected :
    11.   virtual void clicked_button();
    12.   Gtk::Button m_button;
    13. };
    14.  
    15. //constructor
    16. //"pressed" ở đây là label của nút m_button
    17. print_hello::print_hello():m_button("pressed"){
    18.   set_border_width(100);    //--------  method Gtk::Window
    19.   m_button.signal_clicked().connect(sigc::mem_fun(*this, &print_hello::clicked_button));
    20.   add(m_button);              //---------  method of class Gtk::Window
    21.   m_button.show();          //----------- method of Gtk::button
    22. }
    23. //destructor
    24. print_hello::~print_hello(){
    25. }
    26.  
    27. void print_hello::clicked_button(){
    28.   std::cout << "Welcome to gtkmm.\n";
    29. }
    30.  
    31. int main(int argc, char* argv[]){
    32.   Gtk::Main my_kit(argc, argv);
    33.   print_hello hello;
    34.   Gtk::Main::run(hello);
    35.  
    36.   return 0;
    37. }
    - Chúng ta có 1 class print_hello do ta chúng ta định nghĩa, và lớp này sẽ kế thừa từ lớp Gtk::Window, và nó có 1 thành viên là Gtk::Button m_button.
    Tất cả các hàm nào của Gtk:: mình đã chú thích rõ ràng trên đó. Nhìn thoáng quá sao mà nhiều quá, nhìn kĩ lại sao mà ít quá vậy T_T, bắt đầu kết gtkmm rùi nhá T_T.

    Bây h hãy nhìn vào main() còn đơn giản hơn :
    C++ Code:
    1. int main(int argc, char* argv[]){
    2.   Gtk::Main my_kit(argc, argv);
    3.   print_hello hello;
    4.   Gtk::Main::run(hello);
    5.  
    6.   return 0;
    - my_kit là 1 đối tượng của Gtk::Main đòi hỏi cho mọi chuơng trình gtkmm và nó nhận 2 đối mặc định argc và argv. Cái này chỉ là sugar syntax thôi, có 1 dòng cứ học thuộc là được. my_kit là tên do chúng ta đặt, muốn đặt gì đó là tùy.
    - Sau đó ta tạo 1 đối tượng hello và pass nó vào hàm run của Gtk::Main và thế là chúng ta sẽ có cửa sổ nhỏ xinh thế này đây T_T :

    Và khi click vào cái nút press ấy thì tau thấy có 1 dòng chữ Welcome to GTKMM hiện ra, quá cool phải không nào !
    Khi dịch xong thì ta có thể chạy chượng trình bằng cú pháp, ví dụ ta có file executable :
    Code:
     g++  hello.cpp -o hello -Wall -O3 -ansi -pedantic `pkg-config gtkmm-2.4 --cflags --libs`
    Thì ta run nó bằng :
    Code:
     ./hello
    - Nếu các bạn có mọi khó khăn nào trong cách compile source code on Linux, thì nói với mình nhé, mình sẽ chỉ dẫn tối đa .
    Have fun...!

  3. #3
    Ngày gia nhập
    03 2008
    Bài viết
    11

    Và quả thật khi học gtkmm bạn sẽ có cảm giác bạn đang thực sự học C++, nó không như những toolkit khác, nó không sinh code làm cho bạn không thể nào hiểu nổi nó từ đâu ra mà chỉ ngậm ngùi chấm nhận. Học gtkmm bạn càng cảm thấy thích C++ hơn bao h hết
    Em không đồng ý với chỗ này, em cũng chưa hiểu toolkit hay là framework và cái gì sinh code (sinh code tự động?)

  4. #4
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Tại cái này anh nghe nói khi mình drag + drop bên MFC đại loại thế thì nó hay tự động generate codes cho mình, và anh cũng nói thẳng anh chưa coi qua nó bao h T_T. Nhưng quả thật khi anh code gtkmm anh cảm giác nó gần với C++, anh cũng đã in ra 1 xấp tài liệu bên wxWidgets, và cũng đang ngâm cứu nó, nhưng học 2 cái anh cũng hơi bị oải T_T.
    Em không đồng ý với chỗ này, em cũng chưa hiểu toolkit hay là framework và cái gì sinh code (sinh code tự động?)
    Anh cũng hổng hiểu T_T. Anh thì nghĩ toolkit là giống như 1 bộ dụng cụ, còn framework là gì thì anh chịu T_T, chưa làm tới nó bao h. Em có rảnh thì chăm sóc bên wxWidget đi nhé. Anh dạo này vừa ôn lại giải thuật vừa đang chiến đấu với thằng boost + 2 thằng này T_T. hic hic !
    Nhưng em cứ thử gtkmm đi, anh bảo đảm em sẽ mê nó luôn hè hè !

  5. #5
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Signal (tiếp theo...)
    Trong gtkmm, chúng ta có những loại signal cơ bản sau :
    pressed : tính hiệu được phát ra khi 1 button được ấn.
    released : tính hiệu được phát khi 1 button được giải phóng.
    clicked : tính hiệu được phát ra khi 1 button được ấn và giải phóng.
    enter : tính hiệu được phát khi con trỏ chuột được di chuyển qua cửa số button.
    leave : tính hiệu được phát con trỏ chuột rời khỏi cửa sổ button.
    Nhưng phần lớn trong những chương trình của chúng ta chúng ta sẽ chỉ xài clicked.

    I Toogle button :


    - ToggleButtons thì cũng giống như 1 button thường nhưng sự khác biệt là chúng sẽ vẫn hiệu lực cho đến khi chúng ta click 1 lần nữa.
    - Để gọi là trạng thái của ToogleButton thì chúng ta dùng hàm get_active().
    Hàm này sẽ trả về true nếu button is đi xuống.
    - Chúng ta cũng có thể set trạng thái cho ToogleButton bằng hàm set_active(). Và chú ý rằng khi ta set trạng thái cho 1 button như vậy thì nó đồng thời sẽ làm cho tí hiệu "clicked" được phát ra.
    - Chúng ta cũng có thể dùng hàm toggled() để di chuyển qua lại giữa 2 trạng thái lên và xuống. Hàm này sẽ chuyển button trạng thái của 1 button qua lại.
    - Gtk::ToggleButton là 1 trong những lớp hiệu được sử dụng rộng rãi nhất trong trong lớp base Gtk::RadioButton


    II. CheckButton :
    - Gtk::CheckButton là lớp kế thừa từ lớp base : Gtk::ToggleButton. Điểm khác biệt duy nhất giữa 2 thằng này là hình dạng. Chúng ta cũng có thể dùng lại tất cả các phương thức của ToggleButton cho CheckButton.

    Ví dụ :
    C++ Code:
    1. #include <gtkmm/window.h>
    2. #include <gtkmm/checkbutton.h>
    3. #include <gtkmm/main.h>
    4. #include <iostream>
    5.  
    6. //Chúng ta sẽ có tạo 1 class checked_button_example
    7. //kế thừa từ lớp Gtk::Window như mọi ví dụ ở các bài trước.
    8. class checked_button_example : public Gtk::Window{
    9. public :
    10.   checked_button_example();
    11.   virtual ~checked_button_example();
    12. protected :
    13.   Gtk::CheckButton m_button; //Đây là dữ liệu của chúng ta, 1 check button
    14.   virtual void click_one_click(); //hàm này sẽ nhận tín hiệu click
    15. };
    16. //m_button của chúng ta sẽ có tên là something.
    17. checked_button_example::checked_button_example():m_button("something"){
    18.   set_title("wow so cool"); //đây là tên cửa sổ
    19.   set_border_width(10);   //cho nó có độ rộng là 10.
    20.  
    21.   m_button.signal_clicked().connect(sigc::mem_fun(*this,
    22.                                                     &checked_button_example::click_one_click));
    23.   add(m_button); //chúng ta sẽ add button vào.
    24.   show_all_children(); //hàm này sẽ show ra cả cửa sổ con.
    25. }
    26. //Hàm hủy nút, khi xong thì xuất ra Done the job.
    27. checked_button_example::~checked_button_example(){
    28.   std::cout << "Done the job !!!\n";
    29. }
    30.  
    31. //Khi chúng ta click thì nó sẽ xuất ra How do you feel T_T.
    32. //Hàm get_active lúc này sẽ in ra true hay false, khi chúng ta
    33. // có click hay không, chính vì chỗ này mà gtkmm quả thật rất gần với C++ :D
    34. //Nó là sự kết hợp giữa GUI và console
    35. void checked_button_example::click_one_click(){
    36.   std::cout << "How do you feel ?\n";
    37.   std::cout << (m_button.get_active() ? "true" : "false");
    38.   std::cout << "\n";
    39. }
    40.  
    41. int main(int argc, char* argv[]){
    42.   Gtk::Main my_app(argc, argv);
    43.   checked_button_example great_window;
    44.   Gtk::Main::run(great_window);
    45.  
    46.   return 0;
    47. }


  6. #6
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Thumbs up Chuyên đề C++ | Lập trình GUI với gtkmm toolkit

    I. RadioButton :
    - Giống như các loại checkboxes, radio-button cũng kế thừa từ Gtk::ToggleButton, nhưng chúng phải làm việc theo nhóm, và chỉ có 1 RadioButton trong 1 nhóm được chọn 1 lần.
    II.Group :
    Có 2 cách chúng ta để chúng ta tạo 1 nhóm các radio-buttons.
    - Cách 1 là tạo ra các buttons và sau đó gôm chúng lại. Và chỉ có 2 constructors đầu tiên được sử dụng. Trong ví dụ dưới đây chúng ta sẽ đặt 3 radio-buttons vào class của chúng ta.
    C++ Code:
    1. class RadioButtons : public Gtk::Window
    2. {
    3. public:
    4.     RadioButtons();
    5.  
    6. protected:
    7.     Gtk::RadioButton m_rb1, m_rb2, m_rb3;
    8. };
    9.  
    10. RadioButtons::RadioButtons()
    11.   : m_rb1("button1"),
    12.     m_rb2("button2"),
    13.     m_rb3("button3")
    14. {
    15.     //- Tạo ra 1 nhóm các nút tên là group
    16.     //- Add nút rb2 và rb3 vào rb1
    17.     Gtk::RadioButton::Group group = m_rb1.get_group();
    18.     m_rb2.set_group(group);
    19.     m_rb3.set_group(group);
    20. }

    - Chúng ta nói gtkmm rằng bỏ 3 cái nút đó vào cùng 1 group bằng cách dùng 2 hàm get_group() và set_group().
    - Lưu ý chúng ta không thể :
    C++ Code:
    1. m_rb2.set_group(m_rb1.get_group()); //doesn't work
    Bởi vì group đã bị set_group chỉnh sữa trong khi group phải là const.

    Cách thứ 2 để tạo ra 1 nhóm các buttons là tạo ra 1 nhóm trước, sau đó add các button vào trong đó. Ví dụ :
    C++ Code:
    1. RadioButtons::RadioButtons(){
    2.   Gtk::RadioButton::Group group;
    3.   Gtk::RadioButton *m_rb1 = Gtk::manage(new Gtk::RadioButton(group,"button1"));
    4.   Gtk::RadioButton *m_rb2 = manage(new Gtk::RadioButton(group,"button2"));
    5.   Gtk::RadioButton *m_rb3 = manage(new Gtk::RadioButton(group,"button3"));
    6. }
    Chúng ta tạo ra 1 nhóm mới bằng cách khai báo 1 biến tên group của kiểu Gtk::RadiButton::Group. Sau đó chúng ta làm làm cho 3 nút này bằng cách sử dụng 1 constructor để làm chúng là mỗi nút thành 1 thành viên của nhóm.

    Các radio buttons sẽ ở trạng thái "off" khi chúng được tạo ra. Nghĩa khi chúng ta đầu tiên tạo ra 1 nhóm, tất cả các nút đều off. Và chúng ta phải kích hoạt chúng bằng cách dùng hàm set_active();

    Example :
    C++ Code:
    1. #include <gtkmm/window.h>
    2. #include <gtkmm/radiobutton.h>
    3. #include <gtkmm/box.h>
    4. #include <gtkmm/separator.h>
    5. #include <gtkmm/main.h>
    6. #include <iostream>
    7.  
    8. class group_of_radio_buttons : public Gtk::Window{
    9. public:
    10.   group_of_radio_buttons();
    11.   virtual ~group_of_radio_buttons();
    12.  
    13. protected:
    14.   //Các signal handlers:
    15.   virtual void on_button_clicked();
    16.  
    17.   //Các dữ liệu của chúng ta gồm 3 box và 3 nút, 1 thằng phân cách
    18.   //và 1 nút đóng
    19.   Gtk::VBox m_Box_Top, m_Box1, m_Box2;
    20.   Gtk::RadioButton m_RadioButton1, m_RadioButton2, m_RadioButton3;
    21.   Gtk::HSeparator m_Separator;
    22.   Gtk::Button m_Button_Close;
    23. };
    24.  
    25. group_of_radio_buttons::group_of_radio_buttons() :
    26.   m_Box1(false, 10),
    27.   m_Box2(false, 10),
    28.   m_RadioButton1("button1"),
    29.   m_RadioButton2("button2"),
    30.   m_RadioButton3("button3"),
    31.   m_Button_Close("close")
    32. {
    33.   //Tạo tên và độ rộng cho cửa sổ
    34.   set_title("radio buttons");
    35.   set_border_width(0);
    36.  
    37.   //Đặt nút 2, 3 vào cùng nhóm với nhóm của nút 1
    38.   Gtk::RadioButton::Group group = m_RadioButton1.get_group();
    39.   m_RadioButton2.set_group(group);
    40.   m_RadioButton3.set_group(group);
    41.  
    42.    //Add cái box_top vào cửa sổ và cửa sổ chỉ có thể
    43.    //chứa 1 widget
    44.    add(m_Box_Top);
    45.  
    46.  //Add box bên trong và 1 phân cách vào box ngoài
    47.   m_Box_Top.pack_start(m_Box1);
    48.   m_Box_Top.pack_start(m_Separator);
    49.   m_Box_Top.pack_start(m_Box2);
    50.  
    51.   //Tạo border cho box trong
    52.   m_Box2.set_border_width(10);
    53.   m_Box1.set_border_width(10);
    54.  
    55.   //Đặt các radio button cho box1
    56.   m_Box1.pack_start(m_RadioButton1);
    57.   m_Box1.pack_start(m_RadioButton2);
    58.   m_Box1.pack_start(m_RadioButton3);
    59.  
    60.   //Làm nút 2 active lại
    61.   m_RadioButton2.set_active();
    62.  
    63.   //Đặt close button vào box2
    64.   m_Box2.pack_start(m_Button_Close);
    65.  
    66.   //Làm cho nút close trở thành 1 mặc định widget
    67.   m_Button_Close.set_flags(Gtk::CAN_DEFAULT);
    68.   m_Button_Close.grab_default();
    69.  
    70.   m_Button_Close.signal_clicked().connect(sigc::mem_fun(*this,
    71.                                                               &group_of_radio_buttons::on_button_clicked) );
    72.  
    73.   //Show các cửa sổ con
    74.   show_all_children();
    75. }
    76.  
    77. group_of_radio_buttons::~group_of_radio_buttons(){
    78.   std::cout << "Deleting all buttons on process...\n";
    79. }
    80.  
    81. void group_of_radio_buttons::on_button_clicked(){
    82.   std::cout << "CLIKED & SWITCHED !!!!\n";
    83.   hide(); //Dùng để đóng cửa số khi click close.
    84. }
    85.  
    86. int main(int argc, char *argv[]){
    87.   Gtk::Main my_application(argc, argv);
    88.   group_of_radio_buttons buttons;
    89.   Gtk::Main::run(buttons);
    90.  
    91.   return 0;
    92. }

  7. #7
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    I.mem_fun vs ptr_fun :
    - Bây h chúng ta sẽ bắt đầu tìm hiểu kĩ lại hàm đặc trưng trong gktmm mà bữa h chúng ta dùng :
    C++ Code:
    1. m_button1.signal_clicked().connect(sigc::mem_fun(*this, &some_class::on_button_clicked));
    trước khi chúng ta đi tới những ví dụ phức tạp hơn.
    - Đầu tiên xét ví dụ đơn giản sau :
    C++ Code:
    1. #include <gtkmm/button.h>
    2.  
    3. void on_button_clicked()
    4. {
    5.     std::cout << "Hello World" << std::endl;
    6. }
    7.  
    8. main()
    9. {
    10.     Gtk::Button button("Hello World");
    11.     button.signal_clicked().connect(sigc::ptr_fun(&on_button_clicked));
    12. }
    Hàm trên nhận vào 1 ptr_fun của STL chúng ta có 3 nhận xét sau :
    + signal handler ở đây là on_button_clicked.
    + chúng ta gắn signal này vào 1 đối tượng của lớp Gtk::Button, và nó chính là button ở đây.
    + Và khi chúng ta nhấn 1 button thì hàm on_button_clicked sẽ được gọi, kĩ thuật này gọi là call_back và được sử dụng hầu hết trong các toolkit GUI (MFC, GTK+, wxWidget, Qt4...)
    + sigc::ptr_fun() nó sẽ tạo ra 1 slot và thằng sigc::slot này mặc dù nhìn nó giống như 1 hàm nhưng bản chất thực sự của nó là 1 function object ( hay con gọi là functor -> 1 kĩ thuật rất cơ bản trong STL )
    + trong STL chúng ta có 2 kiểu dùng functor cơ bản : ptr_fun và mem_fun. Sự khác biệt của 2 thằng này như sau :
    ) ptr_fun dùng cho các hàm stand-alone hoặc static
    ) mem_fun dùng cho phuơng thức của 1 lớp.
    Và sau đây là ví dụ tương tự khi dùng mem_fun
    C++ Code:
    1. void on_button_clicked();
    2.  
    3. class some_class
    4. {
    5.     void on_button_clicked();
    6. };
    7.  
    8. some_class some_object;
    9.  
    10. main()
    11. {
    12.     Gtk::Button button;
    13.     button.signal_clicked().connect( sigc::ptr_fun(&on_button_clicked) );
    14.     button.signal_clicked().connect( sigc::mem_fun(some_object, &some_class::on_button_clicked) );
    15. }
    Trong các đoạn code ở các bài trước chúng ta thường thấy *this, và nó chính là đối tượng some_object ở đây.

    II.Tạo thêm những đối khác nhận tín hiệu từ những button khác nhau :
    - Đôi khi trong lúc làm việc với nhiều widgets, chúng ta có lẽ sẽ muốn signal handler của chúng ta sẽ nhận thêm 1 số dữ liệu, ví dụ chúng ta sẽ có 2 nút và chúng ta muốn signal handler của chúng ta phân biệt được nút nào sẽ được ấn. Và chúng ta có thể làm được điều này với 1 hàm mới :
    C++ Code:
    1.  sigc::bind()
    Xem ví dụ sau :
    C++ Code:
    1. m_button1.signal_clicked().connect( sigc::bind<Glib::ustring>( sigc::mem_fun(*this, &hello::on_button_clicked), "button 1") );
    Statement trên nói rằng chúng ta sẽ send thêm 1 đối là Glib::ustring ( 1 class string của gtkmm như string C++ ) và nhận vào thêm 1 đối số gọi là button 1. Và tất nhiên trong hàm thành viên của class hello, chúng ta sẽ phải thêm đối này vào và nó sẽ có cấu trúc như sau :
    C++ Code:
    1. virtual void on_button_clicked(Glib::ustring data);

    Và bây h là ví dụ hoàn chỉnh của class hello với 2 button :
    C++ Code:
    1. #include <gtkmm/button.h>
    2. #include <gtkmm/box.h>
    3. #include <gtkmm/window.h>
    4. #include <gtkmm/main.h>
    5. #include <iostream>
    6.  
    7. class hello : public Gtk::Window{
    8. public :
    9.   hello();
    10.   virtual ~hello();
    11. protected :
    12.   virtual void click_please(Glib::ustring x);
    13.   //HBox means : HORIZONTAL BOX, box theo chiều ngang
    14.   Gtk::HBox dy_box1;
    15.   Gtk::Button m_butt1, m_butt2;
    16. };
    17.  
    18. hello::hello():m_butt1("first"), m_butt2("second"){
    19.   set_title("HELLO II");
    20.   set_border_width(10);
    21.   add(dy_box1);
    22.   m_butt1.signal_clicked().connect(sigc::bind<Glib::ustring>
    23.               (sigc::mem_fun(*this, &hello::click_please), "first"));
    24.  
    25.   dy_box1.pack_start(m_butt1);
    26.   //m_butt1.show() là 1 bước quan trọng vì nó sẽ nói với GTK
    27.   //rằng nút này đã hoàn thành và có thể hiện ra bây h.
    28.   m_butt1.show();
    29.   m_butt2.signal_clicked().connect(sigc::bind<-1, Glib::ustring>
    30.               (sigc::mem_fun(*this, &hello::click_please), "second"));
    31.              
    32.   dy_box1.pack_start(m_butt2);
    33.   m_butt2.show();
    34.   dy_box1.show();
    35. }
    36.  
    37. hello::~hello(){
    38.   std::cout << "Done the job...!\n";
    39. }
    40.  
    41. void hello::click_please(Glib::ustring x){
    42.   std::cout << "HELLO : " << x << " was pressed.\n";
    43. }
    44.  
    45. int main (int argc, char *argv[]){
    46.   Gtk::Main my_kit(argc, argv);
    47.   hello my_hello;
    48.   Gtk::Main::run(my_hello);
    49.   return 0;
    50. }

    Demo :

  8. #8
    Ngày gia nhập
    01 2008
    Nơi ở
    Gameloft Studio
    Bài viết
    294

    Tuyệt vời!!! Một ngày nào đó có thể công trình này sẽ có ý nghĩa. Tiếp tục nhé RR

  9. #9
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    T_T Úi, hi bác Zcoder ! Quả thật lúc đầu tui bay vào wxWidget tui văng ra gần 1 chục thước T_T. Chơi với gtkmm vậy mà code sáng hơn rất nhiều, rất gần với C++ không macro gì cả. Nhưng hiện h cũng bắt đầu hoa mắt khi có quá nhiều hàm phải nhớ T_T, bác có phát hiện gì thì cứ đóng góp thoải mái nhé ! Tui cũng vừa dịch lại vừa học thui hi vọng ngày mai sẽ khá hơn 1 tí !

  10. #10
    Ngày gia nhập
    01 2008
    Nơi ở
    Gameloft Studio
    Bài viết
    294

    wxWidget nó y chang MFC. Ai mà biết MFC rồi thì ko có học đọc code cũng hiểu. Chắc RR chưa lập trình MFC chứ gì?

    Còn cái này qtkmm không biết nó có họ hàng gì với QT4 hay ko nhưng mà thấy thư viện nó namespace nhiều quá nên thấy code nó hơi kinh dị

    Chiều tối tui Up cuốn QT4 cho RR nghiên cứu. Cam đoan là code QT4 là sáng nhất trong các opensource GUI đó.

    Hệ thống class của qt4 cũng đẹp nữa: http://doc.trolltech.com/4.0/classes.html. Mình thấy nó cũng ngang ngữa .NET chứ chả chơi. Ko thiếu thứ gì hết XML, HTTP...
    Đã được chỉnh sửa lần cuối bởi ZCoder87 : 07-04-2008 lúc 11:55 AM.

Các đề tài tương tự

  1. Hướng dẫn dùng Ajax Control Toolkit
    Gửi bởi thienthanit trong diễn đàn Tutorials và Thủ thuật lập trình C#, ASP.NET
    Trả lời: 16
    Bài viết cuối: 24-05-2013, 04:10 PM
  2. Sử dụng AjaxFileUpload của bộ control toolkit 3.5
    Gửi bởi tgnhim trong diễn đàn Thắc mắc lập trình ASP.NET
    Trả lời: 3
    Bài viết cuối: 02-04-2013, 09:41 PM
  3. Kỹ thuật C dùng HTK toolkit cho ứng dụng nhận dạng giọng nói!
    Gửi bởi nbinh trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 4
    Bài viết cuối: 23-09-2011, 01:19 PM
  4. không sử dụng được Editor của Ajax Control Toolkit !
    Gửi bởi zerosix1990 trong diễn đàn Thắc mắc lập trình ASP.NET
    Trả lời: 10
    Bài viết cuối: 01-06-2011, 07:32 PM
  5. Thắc mắc sử dụng ajax control toolkit với asp.net
    Gửi bởi caocanha trong diễn đàn Thắc mắc lập trình ASP.NET
    Trả lời: 7
    Bài viết cuối: 25-05-2011, 10:36 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn