ホーム >

QtRuby

Hello world

require 'Qt4'

if $0 == __FILE__
  app = Qt::Application.new(ARGV)
  win = Qt::Label.new("Hello qtruby world")
  win.show
  exit( app.exec )
end

シグナルとスロットの例

require 'Qt4'

class MyWidget < Qt::Widget
  def initialize(parent=nil)
    super
    @quit_button = Qt::PushButton.new("Quit", self)
    layout = Qt::HBoxLayout.new
    layout.addWidget(@quit_button)
    setLayout(layout)

    connect(@quit_button, SIGNAL("clicked()"),
            $qApp, SLOT("quit()"))
  end
end

if $0 == __FILE__
  app = Qt::Application.new(ARGV)
  win = MyWidget.new
  win.show
  exit( app.exec )
end

独自のシグナル・スロットの定義

自分のクラスでスロットを定義する場合、 slotsクラス特異メソッドを使用する。

require 'Qt4'

class MyWidget < Qt::Widget
  def initialize(parent=nil)
    super
    @ok_button = Qt::PushButton.new("OK", self)
    layout = Qt::HBoxLayout.new
    layout.addWidget(@ok_button)
    setLayout(layout)

    connect(@ok_button, SIGNAL("clicked()"),
            self, SLOT("on_ok_button_clicked()"))
  end

  slots "on_ok_button_clicked()"
  def on_ok_button_clicked
    puts "OK"
  end
end

if $0 == __FILE__
  app = Qt::Application.new(ARGV)
  win = MyWidget.new
  win.show
  exit( app.exec )
end

また、独自のシグナルを定義する場合、 signalsクラス特異メソッドを使用する。

require 'Qt4'

class MyWidget < Qt::Widget

  signals "mysignal()"

  def initialize(parent=nil)
    super
    @ok_button = Qt::PushButton.new("OK", self)
    layout = Qt::HBoxLayout.new
    layout.addWidget(@ok_button)
    setLayout(layout)

    connect(@ok_button, SIGNAL("clicked()"),
            self, SIGNAL("mysignal()"))
    connect(self, SIGNAL("mysignal()"),
            self, SLOT("on_ok_button_clicked()"))
  end

  slots "on_ok_button_clicked()"
  def on_ok_button_clicked
    puts "OK"
  end
end

if $0 == __FILE__
  app = Qt::Application.new(ARGV)
  win = MyWidget.new
  win.show
  exit( app.exec )
end

Qtのクラス階層に対してメソッドを追加する

qtrubyではクラス階層のトップがQt::ObjectではなくQt::Baseという別のクラスになっている。 そのため、Qtのクラス階層にメソッドを追加する場合、Qt::Baseに対してメソッドを定義すればよい。

require 'Qt4'

class << Qt::Base
  def define_slot(slot_signature, &block)
    slot_name = slot_signature.split("(")[0]
    slots(slot_signature)
    define_method(slot_name, &block)
  end
end

class MyWidget < Qt::Widget
  def initialize(parent=nil)
    super
    @ok_button = Qt::PushButton.new("OK", self)
    layout = Qt::HBoxLayout.new
    layout.addWidget(@ok_button)
    setLayout(layout)

    connect(@ok_button, SIGNAL("clicked()"),
            self, SLOT("on_ok_button_clicked()"))
  end

  define_slot("on_ok_button_clicked()") do
    puts "OK"
  end
end

if $0 == __FILE__
  app = Qt::Application.new(ARGV)
  win = MyWidget.new
  win.show
  exit( app.exec )
end

Rubyクラスをシグナル・スロットでやり取りする

筆者の知る限りでは、 qtrubyでRubyオブジェクトをシグナルで飛ばすには、 そのオブジェクトをQt::Objectのサブクラスにする必要がある。 スロットのシグネチャは次のプログラムのように、 「const QObject *」を使用する。

require 'Qt4'

class MyObject < Qt::Object
  attr_reader :content
  def initialize(content, parent=nil)
    super(parent)
    @content = content
  end
end

class MyWidget < Qt::Widget

  signals "emit_ruby_obj(const QObject *)"

  def initialize(parent=nil)
    super(parent)
    @ok_button = Qt::PushButton.new("ok", self)
    layout = Qt::HBoxLayout.new
    layout.addWidget(@ok_button)
    setLayout(layout)
    connect(@ok_button, SIGNAL("clicked()"),
            self, SLOT("slot1()"))
    connect(self, SIGNAL("emit_ruby_obj(const QObject *)"),
            self, SLOT("slot2(const QObject *)"))
  end

  def slot1
    emit emit_ruby_obj(MyObject.new([1, 2, 3], self))
  end
  def slot2(obj)
    puts obj.content
  end
  slots "slot1()"
  slots "slot2(const QObject *)"
end

if $0 == __FILE__
  app = Qt::Application.new(ARGV)
  win = MyWidget.new
  win.show
  exit( app.exec )
end