Статьи

GUI приложения с обувью

обувь-значок

Если вы долго программировали на Ruby, вы, вероятно, хотя бы слышали об обуви. Shoes — это инструментарий DSL / GUI, изначально разработанный знаменитой _why The Lucky Stiff. Это также основа для программы Hackety Hack, которая помогает пользователям изучать программирование на Ruby и GUI.

Вы можете найти официальный сайт здесь .

Простое приложение в Shoes выглядит так:

# hello_world.rb
require 'green_shoes'

Shoes.app do
  para "Hello World"
end

Обувь делает создание GUI чертовски легким. Этот учебник охватывает основы и показывает некоторые примеры вещей, которые могут быть созданы с его помощью.

Код в этом уроке доступен на github .

Надевая обувь

Один из самых запутанных моментов в туфлях — это то, что они бывают разных вкусов.

  • Red Shoes — оригинальная платформа Shoes
  • Blue Shoes — реализация QT
  • Фиолетовая обувь — реализация JRuby / SWT
  • Green Shoes — чистая реализация Ruby / GTK2
  • Shoes4 — следующая версия Shoes

На момент написания этой статьи, если вы установите самоцвет обуви и попытаетесь использовать его, вы получите следующее сообщение:

 Sorry, this gem currently does nothing. Team Shoes is working on Gemifying Shoes, and this is just a placeholder until then.

Проект Shoes github долгое время не обновлялся, поэтому похоже, что Team Shoes решили, что gemification Shoes не вошла в их список приоритетов. Одна из причин, вероятно, заключается в том, что Shoes — это не просто библиотека графического интерфейса, это платформа приложений. Он даже поставляется с собственным интерпретатором Ruby.

Похоже, что blue_shoes никогда не выходил из ранних стадий разработки. Просматривая код, многие методы не реализованы, поэтому вы, вероятно, хотите остаться в стороне от этого.

purple_shoes был создан тем же человеком, что и green \ _shoes. Вероятно, это вторая лучшая альтернатива Red Shoes. Я протестировал несколько кроссплатформенных примеров, и они, похоже, сработали. Однако он не обновлялся в течение нескольких лет, поэтому ваш пробег может отличаться. Вам понадобится JRuby, если вы хотите попробовать purple_shoes.

green_shoes — это разновидность обуви GTK2. Кажется, это самая последняя обновленная и наиболее реализованная альтернатива Red Shoes. Не совсем то же самое, но это достаточно близко, если вы просто хотите почувствовать вкус без установки Red Shoes.

У Green Shoes есть страница о различиях между Red Shoes и Green Shoes . Кроме того, вы заметите много «Примечание: Зеленая обувь не поддерживает …» в руководстве. Если вы серьезно относитесь к использованию обуви, вы, вероятно, захотите убедиться, что вы можете заставить Красные ботинки работать или планируете сильно модифицировать Зеленые ботинки.

Похоже, что Team Shoes в настоящее время работает над перезаписью Shoes4. Код доступен на github . К сожалению, похоже, он еще не готов к использованию.

Начиная

У меня были проблемы с установкой платформы Red Shoes, поэтому я буду использовать камень Green Shoes в этом уроке. Поскольку Green Shoes использует GTK2, убедитесь, что у вас установлены библиотеки GTK2, прежде чем пытаться что-либо запускать.

Для начала возьмите камень green_shoes:

 gem install green_shoes

Структура приложения Shoes выглядит следующим образом:

 Shoes.app do
  element/slot(args) do
    element/slot(args) do
      ...etc
    end
  end  
end

В примере в начале статьи «para» создал элемент абзаца с содержимым «Hello World».

 # hello_world.rb
require 'green_shoes'

Shoes.app do
  para "Hello World"
end

В Shoes DSL элементы GUI создаются на месте с использованием методов создания элементов. Это противоречит стандартной практике создания окон, создания макетов, создания виджетов, добавления виджетов в макеты и добавления макетов в окна. Обувь делает это под капотом.

Можно хранить элементы в переменных, чтобы на них можно было ссылаться в другом месте приложения.

 Shoes.app do
  @paragraph = para "This is a paragraph."
  @button = button("change it") do
    @paragraph.text = "Now it says something else."
  end
end

Все переменные в этом руководстве являются переменными экземпляра (с префиксом ‘@’), чтобы не путать их с методами Shoes DSL.

Стеки и потоки

Обувь организует свои элементы двумя способами, которые она называет слотами.

  • стеки — вертикальные
  • потоки — горизонтальные
 # stacks_flows.rb

require 'green_shoes'

Shoes.app do

  stack do
    para "stack item 1", width: 100
    button "stack item 2"  
  end

  flow do
    para "flow item 1", width: 100
    button "flow item 2"
  end
end

Стоит отметить, что в Green Shoes TextBlocks (para, caption и т. Д.) Занимают всю ширину, если ширина не указана. Это верно, даже если TextBlock находится в потоке.

У стеков и потоков может быть установлен запас для разделения элементов.

 # margins.rb
require 'green_shoes'

Shoes.app do

  caption "No margin set:"

  stack do
    para "stack item 1", width: 100
    button "stack item 2" 
  end

  flow do
    para "flow item 1", width: 100
    button "flow item 2"
  end

  caption "Margin: 10"

  stack(margin: 10) do
    para "stack item 1", width: 100
    button "stack item 2" 
  end

  flow(margin: 10) do
    para "flow item 1", width: 100
    button "flow item 2"
  end
end

Иногда желаемая компоновка достигается путем помещения потока внутрь стека и наоборот.

 # flow_inside_stack.rb
require 'green_shoes'

Shoes.app do

  stack do
    para "stack item 1", width: 100

    flow do
      para "flow item 1", width: 100
      button "flow item 2"
    end

    button "stack item 2" 
  end
end

Отвечая на взаимодействие с пользователем

Как и ожидалось в Ruby, Shoes использует блоки для обработки таких событий, как нажатие кнопок или изменение текста.

 # event_handling.rb
# Interactive Shoes elements take an event handler as a block
require 'green_shoes'

Shoes.app do
  stack(margin: 10) do
    @edit_box = edit_box do |e|
      @copy_box.text = @edit_box.text
    end  

    @copy_box = para "what you type in the edit box goes here"

    @button = button("obfuscate") do
      ob_bytes = @copy_box.text.each_byte.map { |b| b+1 }
      @copy_box.text = ob_bytes.map { |b| b.chr}.join
    end
  end
end

Создание программы просмотра инструкций YARV

Основное текстовое поле Shoes создается с помощью #edit_box Вы можете прочитать или установить EditBox#text Вот приложение, которое принимает код Ruby и показывает инструкции виртуальной машины, связанные с ним. Примечание : этот пример не будет работать, если вы используете Purple Shoes.

 # yarv_viewer.rb
# Show YARV instructions for given Ruby code
require 'green_shoes'

Shoes.app(width: 900, height: 550) do
  stack(margin: 10) do
    flow(margin: 10) do
      caption "Ruby Code", width: 400
      caption "YARV Instructions", width: 400
    end
    flow(margin: 10) do
      @code = edit_box(width: 400, height: 400)
      @yarv = edit_box(width: 400, height: 400) 
    end
    flow(margin: 10) do
      @compile_button = button("compile") do
        @yarv.text = RubyVM::InstructionSequence.compile(@code.text).disasm
      end
    end
  end
end

Используя Прогресс-бар Shoes ‘

Обувь обеспечивает прогресс-бар barebones. Он имеет значение #fraction Одна из вещей, которая отделяет Progress от других элементов, заключается в том, что его нужно размещать вручную, по пикселям, а не просто помещать в слот.

 # downloader.rb
# Basic downloader with progress-bar
require 'green_shoes'
require 'open-uri'

Shoes.app(width: 350) do
  title "Downloader"
  stack(margin: 10) do

    # user input
    flow do
      @url_line = edit_line
      @download_button = button("download") do
        url = @url_line.text 
        uri = URI.parse(url)
        filename = File.basename(uri.path)

        Thread.new do
          open(filename, 'wb') do |f|
            f.write(open(url, 
              :content_length_proc => @content_length_proc,
              :progress_proc => @progress_proc
            ).read)
          end
        end
      end
    end

    # labels
    caption "File Size:" 
    @expected_bytes = para ""
    caption "Downloaded:"
    @current_bytes = para ""
    caption "Progress:"
    @progress_bar = progress left: 10, top: 300

    # open-uri event handlers
    @content_length_proc = lambda do |content_length|
        @content_length = content_length
        @expected_bytes.text = content_length
    end

    @progress_proc = lambda do |bytes|
      @current_bytes.text = bytes
      @progress_bar.fraction = bytes / @content_length.round(1)
    end
  end
end

Метод #open

  1. :content_length_proc
  2. :progress_proc

Эти обработчики событий (в данном случае лямбда-выражения) используются для установки @progress_bar.fraction

Упаковочные инструменты CLI

Одним из возможных применений для Shoes является создание простых оболочек для инструментов командной строки, таких как ImageMagick’s convert

 # image_converter.rb
# Basic image converter using ImageMagick
require 'green_shoes'
require 'gtk2'

Shoes.app do
  title "--Image Converter--"

  caption "Image Path:"
  @path_line = edit_line

  button("select image") do
    dialog = Gtk::FileChooserDialog.new(
            "Select Image",
            nil,
            Gtk::FileChooser::ACTION_OPEN,
            nil,
            [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
            [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT])

    if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
      @path_line.text = dialog.filename
    end
    dialog.destroy
  end

  caption "Choose a new image format:"
  list_box items: ["jpg", "png", "gif"] do |list|
    @conversion_type = list.text
  end

  button("convert") do
    @file_path = @path_line.text
    @filename = File.basename(@file_path, '.*')
    @conversion_path = "#{File.dirname(@file_path)}/#{@filename}.#{@conversion_type}"
    if @file_path != @conversion_path
      Thread.new do
        @status.text = "converting..."
        system("convert #{@file_path} #{@conversion_path}")
        @status.text = ""
      end
    else
      alert("The image is already in that format")
    end
  end
  @status = para ""
end

Хотя обувь не предоставляет каких-либо конкретных предметов первой необходимости, иногда их можно взять из других библиотек. В этом примере я позаимствовал GTC FileChooserDialog, чтобы пользователю было проще указывать изображения. Это не очень чисто, но green_shoes все равно использует gtk2 Примечание : это не будет работать с Purple Shoes.

Рисование и анимация

Обувь черпает вдохновение из инструментов анимации, таких как «Обработка», в своих средствах рисования и анимации.

 # drawing.rb
# Show how to draw basic shapes in Shoes
require 'green_shoes'

Shoes.app do
  background darkgray
  fill darkblue
  arrow 10, 10, 100
  fill red
  rect 10, 100, 100
  fill yellow
  oval 10, 200, 50
  strokewidth(2)
  line 10, 300, 100, 300
end

Одна из неожиданностей обуви — то, что цвета могут быть указаны без использования символов или строк. Например, вы бы использовали darkblue, а не: darkblue. Также можно указать цвета с помощью #rgb

Обувь обеспечивает метод #animate Требуется один аргумент — количество кадров в секунду анимации. Вы не собираетесь получать уровни управления, или, конечно, не ActionScript, но этого достаточно, чтобы поиграть.

 # animation.rb
# Shows how to animate a bouncing ball
require 'green_shoes'

Shoes.app do
  fill blue
  @gravity = 0.05
  @velocity = 0.0
  @ball_radius = 60
  @ball = oval(top: 10, 
              left: width / 2 - @ball_radius, 
              radius: @ball_radius)
  button("drop ball") do
    animate(60) do
      @velocity += @gravity
      @ball.top += @velocity 
      if @ball.top > height - @ball_radius * 2
        @ball.top = height - @ball_radius * 2
        @velocity = @velocity * -0.8
      end
    end
  end
end

Если вы никогда ранее не писали код анимации, позиция, установленная после проверки границы в конце, может быть не интуитивной. По сути, когда «шар» пересекает границу («земля»), условие выполняется. Даже после изменения скорости условие остается верным, поэтому скорость просто будет снова изменена… и снова, заставляя шар дрожать вокруг границы
пока не кончится энергия. Край шара установлен на границе, чтобы предотвратить это и сохранить иллюзию, что мяч отскакивает от него. Казалось бы, очевидным решением этой проблемы было бы использование оператора ==, но крайне маловероятно, что край шара будет находиться точно на границе на любом данном кадре.

Вывод

Обувь приносит хорошие идеи и идеально подходит для небольших, игрушечных проектов. К сожалению, если вы хотите сделать что-то серьезное с этим, некоторые DIY, вероятно, будут вовлечены по нескольким причинам:

  • Усилия по разработке были поделены между различными вкусами, и в настоящее время нет жемчужины Red Shoes.
  • Обувь никогда не предназначалась для полной замены стандартной библиотеки GUI. Он был создан в основном как образовательный инструмент.
  • По крайней мере с Green Shoes, сообщения об ошибках кажутся нарушенными Что бы ни случилось, я только когда-либо видел общую ошибку GLib. Отладка не будет легкой.

Обувь имеет много особенностей, которые не были рассмотрены в этом уроке. Если вы хотите узнать больше, обязательно ознакомьтесь со следующими ресурсами: