Rubby/gtk3+glade 3에서 DatePicker 처리

16048 단어 GTK3Rubyglade

전언


gtk는 DatePicker가 없어도 사용하기 힘들어요...이렇게 불평하면 @kojix2씨와 팝오버의 조합도 이루어질 수 있습니다!나에게 이런 건의를 했다.
루비로 앞머리를 살짝 덮어주고 싶은 GUI 부분은 빌딩 도구로 멍하니 쓰고 싶었지만, wxWidget에서 사용할 수 없는 현재, QT 크리에이터나 자바FX Sceneditor의 두 번째 선택이라고 생각하고 투덜거리는 곳에서 이런저런 답장을 받았다.
gtk3 코드를 제시했기 때문에 gland로 DatePicker인지 DateChooser인지, 날짜를 선택할 수 있는 텍스트 상자(Gtk:Entry)의 기록을 만들어 보았습니다.아니면 전에 쓴 필기를 잊어버린다든가.
※ gtk가 무엇인지 모르니 용어 등에 오류가 있으면 지적해 주십시오.

차리다


동작의 전제는 루비2다.7,gtk3,glade 3.36.0.
루비는 간단하게 가져올 수 있지만, Windows의glide에는 약간의 함정이 있으니, 아래의 내용을 참고하십시오.

MacOS 및 UnixLikeOS


데비안이면 앱+gem, 맥OS면 홈brew면 뭐든지 돼요.

Windows


Windows에서glide공식 사이트를 사용하려면 실행 2진법은ltk2용 등 오래된 것만 배치합니다.
그래서 scoop ms2를 사용하기로 결정했습니다.
(scoop인체의 도입에 관하여 참고할 수 있음기타 Qita 기사)
ms2를 설치한 후 ms2의 bash에pacman으로ltk의 라이브러리와glade3을 설치합니다.
scoop으로 직접 gland를 설치하는 것이 아니라는 것을 주의하십시오.
$ pacman -S mingw-w64-x86_64-gtk3 mingw-w64-x86_64-glade

$ /mingw64/bin/glade
위에서 말한 바와 같이glide가 시작될 수 있다면 준비가 완료되었습니다(ruby도 준비하세요)

글래드를 발톱으로 삼다


gtk의 유파를 따르다나는 발톱을 만들러 간다.
인터넷에서 glide 화면의 메뉴를 비유하면 HTML/BODY는 맨 윗층(≈ 창)이고 사용자 조작을 동반하는 버튼과 텍스트 필드는 Control(Button, Entry 등), 탭과 이미지는 Display, div는 용기(GtkBox 등)이다.
이번에는 텍스트 필드 (Gtk Entry) 에 초점을 맞출 때 달력에 있는 위젯을 표시하고 싶어서 주요 창 외에 팝오버 용기를 만들어야 한다.

간신히 이걸 만들어 달력에 어제~내일 선택 버튼을 달았다.끊임없이 변화하는 나.
나중에 루비에서 호출할 때 위젯마다 ID로 이름을 지정합니다.
또한 신호 라벨에서 버튼 클릭 등 이벤트를 선택하고 실행하는 방법을 처리 프로그램으로 등록한다.
루비가 실행될 때 프로그램 등록 방법이 없으면 오류가 발생할 수 있습니다. 주의하십시오.
저장됩니다.gland 파일은 XML입니다.

중요한 부분


DatePicker의 GtkEntry를 호출하는 신호focus-in-이벤트 이벤트에서 포커스 오버를 표시합니다.
하지만 반대로 초점이 빗나갔을 때 팝오버를 끄면 당연한 일이지만 캘린더가 작동하지 않도록 주의해야 한다.
Calender에서 날짜를 두 번 눌렀을 때, day-select-double-click 신호 분배 프로세서
PopOver 디스플레이를 닫는 조건으로 '닫기' 단추를 만들고 cliccked 신호로visible=가짜로 설정합니다.

조작하는 리비아


왼쪽 창에서 GtkWindow를 선택한 상태에서 아래 기어 버튼을 눌러 실행 시 미리보기를 미리 볼 수 있습니다.
예전의 비주얼 베이스와 델피의 기준은 창 아래에서 버튼 종류를 자유롭게 설정할 수 있었지만gtk에서는 기본적으로 용기 등에 포장한 후 추가하여 자동으로 배치했다.
자유롭게 배치하려면 GtkFixed라는 컨테이너를 사용하세요.Shift 키를 누른 채 Fixed에 배치된 부품을 드래그할 수 있습니다.
GUI 구조기지만 위젯의 이동이 원활하지 않은 glade는 봉인된 라벨에서 위치를 이동하는 순서로 조정됩니다.
다른 박스로 이동하고 싶을 때 컷으로 Paste...

설치용 코드 만들기


일부 mvc의 시도가 추가되었기 때문에 간단한 코드는 참고하세요원자재 트위터...
app.rb
# frozen_string_literal: true

%w[pp gtk3 date observer].each { |lib| require lib }

class ObjectController
  include Observable
  attr_reader :content

  def content=(object)
    @content = object
    @content.add_observer(self)
    @content
  end

  def update
    changed
    notify_observers
    self
  end
end

class View
  attr_reader :widget

  def controller=(c)
    @controller = c
    @controller.add_observer(self)
    c
  end
end

class State
  include Observable
  def initialize
    @select_date = Date.today
  end

  attr_reader :selected_date

  def selected_date=(date)
    @selected_date = date
    changed
    notify_observers
    date
  end
end

class SelectedDateView < View
  def initialize(parent_builder)
    @widget = parent_builder.get_object('entrydate')
    @widget.signal_connect('changed') do
      @controller.content.selected_date = value
      true
    end
  end

  def value
    @widget.text
  end

  def value=(f)
    @widget.text = f.to_s
  end

  def update
    self.value = @controller.content.selected_date
    self
  end
end

class GyoumuApp
  def initialize
    @select_date = Date.today

    @builder = Gtk::Builder.new(file: 'glade1.glade')

    @seldate_controller = ObjectController.new
    @seldate_controller.content = State.new
    @seldate_view = SelectedDateView.new(@builder)
    @seldate_view.controller = @seldate_controller

    @win = @builder.get_object('main')
    @date_picker = @builder.get_object('date_picker') # PopOver
    @calendar = @builder.get_object('calendar') # PopOverのなかのCalendar

    @buf_code = @builder.get_object('entrybuffer1')
    @buf_code.text = 'K6205'

    @btn_yday = @builder.get_object('select_yesterday')
    @btn_tday = @builder.get_object('select_today')
    @btn_tmrw = @builder.get_object('select_tomorrow')

    # PopOver内のボタンはruby上からシグナルハンドラを設定する
    @btn_yday.signal_connect('clicked') do
      select_day(-1)
    end
    @btn_tday.signal_connect('clicked') do
      select_day(0)
    end
    @btn_tmrw.signal_connect('clicked') do
      select_day(1)
    end

    @builder.connect_signals { |handler| method(handler) } # handler は String
  end

  def select_day(day)
    @seldate_controller.content.selected_date = Date.today + day
    click_dateclose
  end

  # [✕] が押された時にアプリを終了する
  def on_main_destroy
    Gtk.main_quit
  end

  # entrydateにフォーカスが移ったとき
  def focus_in_entrydate
    @date_picker.visible = true
  end

  # calendarの日付をダブルクリックしたとき
  def dblclick_date
    @seldate_controller.content.selected_date = sprintf('%04d-%02d-%02d', @calendar.year, @calendar.month, @calendar.day)
    click_dateclose
  end

  # date_pickerでキャンセルボタンを押下
  def click_dateclose
    @date_picker.visible = false
  end
end

class App < GyoumuApp
  def initialize
    super
    @win.show_all
    Gtk.main
  end
end
App.new

총결산


잡다한 창고 여기.
gtk3 라이브러리는 Gtk:Builder입니다.new에서gland 파일을 읽으면 한꺼번에 사용할 수 있어서 편리해요.
WxWidget의 DatePicker 같은 완제품 부품은 조금씩 사용할 수 있으면 편리하지만, 이번처럼 독자적인 버튼을 추가하려고 할 때는 원활하게 돌릴 수 없다.나는 gtk가 유닉스 스타일의 방법으로 해결할 수 있다는 것을 발견했다.
그냥 귀찮아서.
gland의 설정을 보면 다루기 어려운ltk로 놀린 부분은 상당히 작다.
반대로 생gtk는 애플릿에 대해 상당한 의식을 가져야 하기 때문에 MVM의 스타일이 그립다...

좋은 웹페이지 즐겨찾기