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

GTK-rs 튜토리얼 2강 Click Counter

날짜
2023년 08월 10일
생성자
ShalomShalom
카테고리
gtk
작성일
2023년 08월 10일
태그
rust
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()을 해야합니다
Widget의 경우 기본적으로 Clone이 구현이 되어있습니다
이 때의 클론은 Value Copy가 아닌 Refrence count가 증가가 되며 ref가 copy가 됩니다
 

댓글

guest