Behandle DatePicker mit Ruby / gtk3 + glade3

Präambel

Wenn gtk keinen DatePicker hat und es schwer zu bedienen ist ... Wenn Sie sich fragen, kann @ kojix2 dies mit gtk3 in Kombination mit PopOver tun! Beriet mich.

Ich möchte eine kleine Front-End-GUI mit Ruby abdecken, ich möchte den GUI-Teil mit einem Builder-Tool schreiben, aber jetzt, da wxWidget nicht mehr verwendet werden kann, habe ich mich beschwert, dass es eine Wahl zwischen QT Creator und JavaFX Scene Editor war. Ich habe so eine Antwort bekommen. Da Sie mir den Code von gtk3 gezeigt haben, habe ich versucht, ein Textfeld (Gtk :: Entry) zu erstellen, in dem DatePicker, DateChooser oder Datum mit Lichtung ausgewählt werden können. Oder besser gesagt, ein Memo, das Sie schreiben müssen, bevor Sie es vergessen.

Vorbereitung

Die Betriebsannahmen sind ruby2.7, gtk3, glade 3.36.0. Ich denke, Ruby ist einfach zu installieren, aber es gab eine kleine Falle in der Lichtung unter Windows. Bitte beachten Sie Folgendes.

macOS und UnixLikeOS

Für Debian kann apt + gem verwendet werden, und für macOS kann Homebrew verwendet werden.

Windows

Wenn Sie sich die offizielle Website ansehen, um Glade unter Windows zu verwenden, können Sie feststellen, dass die Ausführungsbinärdatei nur alt ist, z. B. für gtk2. Also habe ich beschlossen, msys2 mit scoop zu verwenden. (Informationen zur Einführung von scoop finden Sie in Ein weiterer Qiita-Artikel)

Installieren Sie nach der Installation von msys2 die gtk-Bibliothek und glade3 mit pacman auf der Bash von msys2. Bitte beachten Sie, dass Sie glade nicht direkt mit scoop installieren.

$ pacman -S mingw-w64-x86_64-gtk3 mingw-w64-x86_64-glade

$ /mingw64/bin/glade

Wenn Sie wie oben mit der Lichtung beginnen können, sind Sie bereit (bitte bereiten Sie auch Rubin vor).

Mache einen Fluss mit Lichtung

Ich werde einen Fluss nach dem Stil von gtk (?) Machen. Wenn Sie das Menü auf dem Glade-Bildschirm mit dem Web vergleichen, ist HTML / BODY die oberste Ebene (≒ Fenster). Schaltflächen und Textfelder mit Benutzeroperationen sind Steuerung (Schaltfläche, Eingabe usw.), Anzeigebeschriftungen und Bilder sind Anzeige, div Ist es ein Container (GtkBox usw.)?

Dieses Mal, wenn das Textfeld (GtkEntry) fokussiert ist, möchte ich das Widget im Kalender anzeigen. Erstellen Sie daher zusätzlich zum Hauptfenster einen Container für PopOver.

image.png

Da ich es selbst machen muss, werde ich zusätzlich zum einfachen Kalender eine Schaltfläche hinzufügen, um gestern bis morgen auszuwählen. Ich ändere mich.

Geben Sie jedem Widget einen Namen nach ID, damit Sie später von Ruby aus anrufen können. Registrieren Sie außerdem eine Methode als Handler, die ein Ereignis wie einen Klick auf eine Schaltfläche ausführt, indem Sie es auf der Registerkarte Signal auswählen. Bitte beachten Sie, dass ein Fehler auftritt, wenn bei der Ausführung von Ruby keine Methode als Handler registriert ist.

Die gespeicherte .glade-Datei ist XML.

Der ekelhafte Teil

Schreiben Sie einen Handler in das Signal Focus-in-Event-Ereignis von GtkEntry, der DatePicker aufruft, damit PopOver angezeigt wird, wenn der Fokus kommt. Wenn Sie PopOver jedoch schließen, wenn der Fokus verloren geht, kann der Kalender natürlich nicht bedient werden. Seien Sie also vorsichtig.

Weisen Sie dem Tag-Auswahl-Doppelklick-Signal einen Handler zu, wenn Sie auf ein Datum im Kalender doppelklicken

Erstellen Sie eine Schaltfläche zum Schließen, um die PopOver-Anzeige auszuschalten, und setzen Sie im angeklickten Signal sichtbar = falsch.

Operation Trivia

Wenn GtkWindow im linken Bereich ausgewählt ist, drücken Sie die Getriebetaste unten, um eine Laufzeitvorschau anzuzeigen.

Im alten Visual BASIC und Delphi war es Standard, dass Schaltflächen frei unter dem Fenster angeordnet werden konnten, aber in gtk scheint es, dass es im Grunde genommen in einem Container usw. verpackt, hinzugefügt und automatisch angeordnet ist. Verwenden Sie für die kostenlose Platzierung einen Container namens GtkFixed. Sie können das in Fixed platzierte Widget verschieben, indem Sie beim Ziehen die Umschalttaste gedrückt halten.

Glade, ein GUI-Builder, der Widgets jedoch nicht weiter verschieben kann, nimmt Anpassungen vor, indem er die Reihenfolge der Positionen auf der Registerkarte "Packen" verschiebt. Wenn Sie es in eine andere Box verschieben möchten, schneiden Sie es aus und fügen Sie es ein ...

Implementierungscode schreiben

Es gibt einen Teil, den ich mit mvc ausprobiert habe. Einen einfachen Code finden Sie unter Original Tweet ...

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') #Kalender in PopOver

    @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')

    #Mit den Schaltflächen in PopOver werden Signalhandler von Ruby festgelegt
    @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 ist String
  end

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

  # [✕]Beenden Sie die App, wenn Sie gedrückt werden
  def on_main_destroy
    Gtk.main_quit
  end

  #Wenn sich der Fokus auf das Eingabedatum verschiebt
  def focus_in_entrydate
    @date_picker.visible = true
  end

  #Wenn Sie auf ein Datum im Kalender doppelklicken
  def dblclick_date
    @seldate_controller.content.selected_date = sprintf('%04d-%02d-%02d', @calendar.year, @calendar.month, @calendar.day)
    click_dateclose
  end

  # date_Drücken Sie die Abbrechen-Taste mit der Auswahl
  def click_dateclose
    @date_picker.visible = false
  end
end

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

Zusammenfassung

Klicken Sie hier für verschiedene Repositories (https://github.com/paichi81/glade_tut1)

Die gtk3-Bibliothek ist praktisch, da Sie die Glade-Datei mit Gtk :: Builder.new lesen und schnell verwenden können.

Es ist praktisch, vorgefertigte Teile wie den DatePicker von WxWidget schnell zu verwenden. Wenn Sie jedoch wie diesmal eine eigene Schaltfläche hinzufügen möchten, ist es nicht einfach, sich umzudrehen. Es stellt sich heraus, dass gtk mit einem Unix-ähnlichen Ansatz gelöst werden kann. Es ist nur ein Ärger ...

In Bezug auf die Lichtungseinstellungen sind die Teile, die mit gtk manipuliert werden können, an denen man sich nur schwer festhalten kann, sehr detailliert. Um es anders herum auszudrücken, raw gtk muss sich der Widgets sehr bewusst sein, deshalb vermisse ich so etwas wie MVVM.

Recommended Posts

Behandle DatePicker mit Ruby / gtk3 + glade3
[Ruby] Behandeln Sie Instanzvariablen mit Instanzmethoden
Gerät mit Schienen handhaben
Behandeln Sie JSON mit minimal-json
Erste Schritte mit Ruby
Evolve Eve mit Ruby
Ich habe DI mit Ruby versucht
GraphQL Client beginnend mit Ruby
Ruby: Mail mit Starttls senden
Formatieren Sie Ruby mit VS-Code
Wie man ganze Zahlen mit Rubin überprüft
[Ruby] Problem mit der if-Anweisung
Studieren bei CodeWar (Rubin) ⑤ proc
Verwenden Sie Ruby mit Google Colab
Erste Schritte mit Ruby-Modulen
[ruby] Eine Methode mit einem Argument aufrufen
Behandle Daten mit Javascript (moment.js)