GTK-rs 튜토리얼 2강 Click counter
GTK-rs 튜토리얼 2강 Click counter

GTK-rs 튜토리얼 2강 Click counter

작성자
Shalom KimShalom Kim
카테고리
Rust
태그
ui/ux
gtk
오늘은 식상하지만 버튼을 클릭하면 카운트가 증가하는 튜토리얼을 진행해보겠습니다
 
notion image

라벨 추가

먼저 라벨을 추가해봅니다
라벨 인스턴스를 생성하는 방법은 2가지가 있습니다
첫 번째 방법은 다음과 같습니다
let label = gtk::Label::new(Some("0")); window.add(&label);
두 번째 방법은 builder를 활용하여 만들 수 있습니다
let label = gtk::Label::builder().label("0").build(); window.add(&label);
두 번째 방법이 뭔가 번거로워 보이지만 다음처럼 이용하면 왜 빌더를 사용하는지 알 수 있습니다
let label = gtk::Label::builder() .label("0") .width_request(20) .height_request(15) .expand(true) .build(); window.add(&label);
위와 같이 원하는 모양을 빌더 패턴을 통해 한 줄로 만들 수 있습니다
 
해당 라벨을 윈도우에 추가해봅니다
notion image
 
엥? 라벨만 표시가 되고 버튼은 표시가 되지 않습니다
 
그 이유는 다음과 같습니다
gtk에서 윈도우는 하나의 자식 위젯을 가질 수 있습니다
따라서 일반적으로 윈도우는 자식을 컨테이너 위젯을 갖게 됩니다
  • 예) Box, Grid 등등
우리는 Box 컨테이너를 사용해 보겠습니다

박스 추가

박스는 방향을 가진 list 형태의 컨테이너 입니다
fn build_ui(application: &gtk::Application) { let window = gtk::ApplicationWindow::new(application); window.set_title("First GTK+ Program"); window.set_border_width(10); window.set_position(gtk::WindowPosition::Center); window.set_default_size(350, 70); let label = gtk::Label::builder() ... .build(); let button = gtk::Button::with_label("Click me!"); let v_box = gtk::Box::builder() .orientation(gtk::Orientation::Vertical) .child(&label) // 라벨 추가 .child(&button) // 버튼 추가 .build(); window.add(&v_box); window.show_all(); }
notion image
박스로 위젯들을 감싸게 되면 우리가 원하는 모양대로 화면이 표시가 됩니다

이벤트

이제 버튼 클릭 이벤트를 이용하여 숫자를 증가시켜보겠습니다
gtk에서는 이벤트와 콜백을 연결 시켜줄 때엔 connect를 이용을 합니다
위젯.connect("{이벤트 이름}", after, 콜백);
💡
after는 해당 기본 이벤트 콜백 동작하기 전이나 후에 실행할 지를 결정하는 bool값입니다
그리고 버튼 클릭과 같은 일반적인 이벤트들은 connect_{이벤트} 등으로 이미 구현이 되어있습니다
우리는 connect_clicked를 이용해볼 것입니다
use gtk::prelude::*; fn build_ui(application: &gtk::Application) { ... let button = gtk::Button::with_label("Click me!"); button.connect_clicked(|_button| { println!("clicked!"); }); ... window.show_all(); }
위의 코드를 실행하면 이제 클릭할 때마다 clicked!가 커맨트 창에 표시가 됩니다
notion image

이벤트에서 라벨 편집

fn build_ui(application: &gtk::Application) { ... { let label = label.clone(); button.connect_clicked(move |_button| { let count: u32 = label.text().parse().unwrap(); label.set_text(&(count + 1).to_string()); }); } ... window.show_all(); }
먼저 label의 소유권을 클로져에게 넘겨야합니다
따라서 label을 clone()을 해야합니다

클론 추가 설명

사실 clone에는 strong 클론과 weak 클론이 있습니다 strong 클론이란 예제처럼 clone을 이용하여 ref count를 증가를 시키는 방법이고 weak는 당장 참조를 하지않고 필요한 순간에 참조를합니다 이 때 ref의 value가 존재하면 ref count 값을 증가시키고 존재하지 않는다면 None을 반환을 시키는데요 이는 나중에 clone 매크로를 다루면서 자세히 알아봅시다
 
Widget의 경우 기본적으로 Clone이 구현이 되어있습니다
이 때의 클론은 Value Copy가 아닌 Reference count가 증가가 되며 ref가 copy가 됩니다
 
이제 다시 cargo run 을 실행하여 버튼을 클릭하면 숫자가 증가합니다!
 

댓글

guest