Archive:Development/Languages/Ruby (zh CN): Difference between revisions

From KDE TechBase
No edit summary
m (AnneW moved page Development/Languages/Ruby (zh CN) to Archive:Development/Languages/Ruby (zh CN) without leaving a redirect: Obsolete)
 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Template:I18n/Language Navigation Bar|Development/Languages/Ruby}}
{{Template:I18n/Language Navigation Bar_(zh_CN)|Development/Languages/Ruby}}
[[Image:ruby.png]]
[[Image:ruby.png]]


Line 8: Line 8:
[http://www.pragmaticprogrammer.com/titles/ctrubyqt/ Rapid GUI Development with QtRuby] (使用Qt 3.x)已经出版。
[http://www.pragmaticprogrammer.com/titles/ctrubyqt/ Rapid GUI Development with QtRuby] (使用Qt 3.x)已经出版。


作为[[Development/Languages/Smoke|基于 Smoke]] 的绑定,意味着他们提供完整使用大多数 KDE 4.x 和Qt 4.x类.
作为[[Development/Languages/Smoke|基于 Smoke]] 的绑定,意味着他们提供完整存取大多数 KDE 4.x 和Qt 4.x类.


= QtRuby =
= QtRuby =
Hello world例子:
Hello world例子:
<code>
<syntaxhighlight lang="ruby">
#!/usr/bin/ruby -w
#!/usr/bin/ruby -w
require 'Qt4'
require 'Qt4'
Line 20: Line 20:
hello.show
hello.show
a.exec
a.exec
</code>
</syntaxhighlight>


Hello Qt例子;更 'Rubyish'的方式:
Hello Qt例子;更 'Rubyish'的方式:


<code>
<syntaxhighlight lang="ruby">
require 'Qt4'
require 'Qt4'


Line 49: Line 49:
     exec
     exec
end
end
 
</syntaxhighlight>
</code>


= 当前 API覆盖率一览 =
= 当前 API覆盖率一览 =


== 可用调用 ==
== 可用调用 ==
You can call all Qt public and protected methods, and all friend methods such as bitBlt() etc
你可以呼叫 Qt 所有的公用(public)和保护(protected)方法,以及所有 friend 方法,如bitBlt()
== 虚方法 ==
== 虚方法 ==


All virtual methods can be overridden, not just event handlers
所有的虚拟方法都可以被覆盖,不仅仅是事件处理


== 配置属性 ==
== 配置属性 ==
'foobar = 5' is a synonym for 'setFooBar(5)'
「foobar = 5」是「setFooBar(5)」的同义词
 
==使用 CamelCase 或小写加底线的名称都可以==


==Use either CamelCase or lowercase with underscore naming==
在方法的命名中任何底线被取消,而接续的字符大写化。例如,您可以使用这两种形式来呼叫相同的方法:


Any underscores in method names are removed, and the following character is capitalised. For example, you can use either of these two forms to call the same method:
<syntaxhighlight lang="ruby">
      create_standard_status_bar_action()
create_standard_status_bar_action()
      createStandardStatusBarAction()
createStandardStatusBarAction()
</syntaxhighlight>


==操作符重载==
==操作符重载==


The full range of Qt operator methods is available, for example:
Qt 所有的操作符方法皆可用,例如:


      p1 = Qt::Point.new(5,5)  => (5, 5)
<syntaxhighlight lang="ruby">
      p2 = Qt::Point.new(20,20) => (20, 20)
p1 = Qt::Point.new(5,5)  => (5, 5)
      p1 + p2                  => (25, 25)
p2 = Qt::Point.new(20,20) => (20, 20)
p1 + p2                  => (25, 25)
</syntaxhighlight>


==声明信号和槽(Signals和Slot)==
==声明信号和槽(Signals和Slot)==


Signals and slots are declared as list of strings like this:
讯号和槽宣告为如下的字符串列表:


      slots 'setColor(QColor)', 'slotLoad(const QString&)'..
<syntaxhighlight lang="ruby">
      signals 'clicked()'..
slots 'setColor(QColor)', 'slotLoad(const QString&)'..
signals 'clicked()'..
</syntaxhighlight>


For slots and signals without arguments you can use Ruby symbols:
对于槽和不带参数讯号,你可以使用 Ruby 符号:


      slots :slotLoad
<syntaxhighlight lang="ruby">
      signals :clicked
slots :slotLoad
signals :clicked
</syntaxhighlight>
          
          
Currently C++ type signatures must be used, a future version of QtRuby will allow ruby type signatures instead.
Currently C++ type signatures must be used, a future version of QtRuby will allow ruby type signatures instead.


Connect slots and signals like this:
像这样连接(connect)槽和讯号:
 
<syntaxhighlight lang="ruby">
Qt::Object.connect( @colormenu, SIGNAL( "activated(int)" ),
                  self, SLOT( "slotColorMenu(int)" ) )
</syntaxhighlight>
 
There is also two another possibilities:


      Qt::Object.connect( @colormenu, SIGNAL( "activated(int)" ),
<syntaxhighlight lang="ruby">
                        self, SLOT( "slotColorMenu(int)" ) )
connect(:mysig, mytarget, :mymethod))
connect(SIGNAL('mysignal(int)'), mytarget, :mymethod))
</syntaxhighlight>


Or you can connect signal to a block:
或者,您可以连接讯号到区块:


      quit_button.connect(SIGNAL :clicked) { $qApp.quit }
<syntaxhighlight lang="ruby">
quit_button.connect(SIGNAL :clicked) { $qApp.quit }
</syntaxhighlight>


And emit signals like this:
和这样发出(emit)讯号:


      emit colorChanged( black )
<syntaxhighlight lang="ruby">
emit colorChanged( black )
</syntaxhighlight>


==构造器==
==构造器==


You can call constructors in the conventional style:
你可以用普通风格呼叫建构子:


       quit = Qt::PushButton.new("Quit", self, "quit")
       quit = Qt::PushButton.new("Quit", self, "quit")


Or you can pass a block if you prefer:
或者,您可以传递区块,如果你喜欢的话:


       w = MyWidget.new { setCaption("foobar") }
       w = MyWidget.new { setCaption("foobar") }
Line 128: Line 149:
==垃圾回收==
==垃圾回收==


When a ruby instance is garbage collected, the underlying C++ instance will only be deleted if it isn't 'owned' by a parent object. Normally this will 'just work', but there are occasions when you need to delete the C++ ahead of garbage collection, and whether or not it has a parent. Use the dispose(), isDisposed() and disposed? methods like this:
ruby 实例垃圾回收时,如果不是被父对象「拥有」,基本的 C++ 实例只会删除。通常这会「正常运作」,但有时您需要在垃圾回收之前删除 C++,不管它是否有父亲。使用 dispose()、isDisposed() disposed? 方法像是这样:


       item2.dispose
       item2.dispose
Line 206: Line 227:
==字符串国际化==
==字符串国际化==


QtRuby supports $KCODE values of 'u', 'e' and 's' or the corresponding '-K' options from the command line. Qt Designer .ui files have UTF-8 strings so if you use any 8 bit UTF-8 characters, you will need to set $KCODE='u' or use the -Ku command line option.
QtRuby 支持'u''e' 's' 的 $KCODE 值或命令行的对应 '-K'选项。Qt Designer .ui 文件有 UTF-8 字符串,因此,如果您要使用任何8位的 UTF - 8 字符,您将需要设定 $KCODE='u' 或使用 -Ku命令行选项。


=Other capabilities and offerings=
=其他功能和产品=


==Qt Designer==
==Qt Designer==


A 'rbuic4' tool is included in qtruby/tools/rbuic to compile .ui files into ruby code. As described above, Qt Designer uses UTF-8. In addition to the options in the original uic C++ utility an '-x' flag has been added. This will generate a top level stub in the code:
「rbuic4」工具包含在qtruby/tools/rbuic,用于编译 .ui 檔加入到 Ruby 程序代码中。如上所述,Qt Designer 使用UTF-8。除了原始的 uic C++ 实用工具的选项还要加上 '-x' 标签。This will generate a top level stub in the code:


       $ rbuic mainform.ui -x -o mainform.rb
       $ rbuic mainform.ui -x -o mainform.rb
Line 270: Line 291:
==API参考==
==API参考==


Use the bin/rbqtapi tool to discover which methods are available in the QtRuby api. This command:
使用 bin/rbqtapi 工具,以了解 QtRuby api 提供哪些方法。指令:


    $ rbqtapi Qt::TextEdit
    $ rbqtapi Qt::TextEdit


Will list all the methods in the Qt::TextEdit class
将列出 Qt::TextEdit 类别中所有的方法


    $ rbqtapi -rsetCaption  
    $ rbqtapi -rsetCaption  


Lists all methods whose names contain the string 'setCaption'
列出所有名称包含字符串'setCaption'的方法


==例子==
==例子==


The best way to start programming QtRuby is to look at some existing code and start messing with it.. The are various samples under qtrubyexamples and korundum/examples.
入门 QtRuby 程序设计的最佳方式是看一些现有的程序代码,并开始弄乱它。在 qtrubyexamples korundum/examples 中有各式各样例子。


=KDE相关信息=
=KDE相关信息=


Instead of <code>require 'Qt4'</code>, use <code>require 'korundum4'</code> for KDE programs.
KDE 程序不是用 <syntaxhighlight lang="text">require 'Qt4'</syntaxhighlight>,而是用 <syntaxhighlight lang="text">require 'korundum4'</syntaxhighlight>


The KDE K* classes such as KApplication are renamed as KDE::Application. The other KDE classes are in the KParts::, KIO:: or DOM:: namespaces, with the same names as their C++ counterparts.
KDE K* 类别,例如 KApplication 被重命名为 KDE::Application。其他的 KDE 类别在KParts::、KIO:: DOM:: 名称空间(namespaces)中,使用相同的名称在它们的 C++ 对应。


Use the 'rbkdeapi' script to introspect the Korundum api from the command line. For example:
在命令行使用「rbkdeapi」脚本来查阅 Korundum api。例如:


       $ rbkdeapi KDE::Action
       $ rbkdeapi KDE::Action


Will list all the methods in the KDE::Action class. There are currently (as at KDE 3.3 beta 2) 977 classes/30841 methods in the Smoke library runtime, so the coverage of the Qt/KDE api is pretty complete.
将列出在 KDE::Action 类别中所有的方法。There are currently (as at KDE 3.3 beta 2) 977 classes/30841 methods in the Smoke library runtime, so the coverage of the Qt/KDE api is pretty complete.


=构建依赖=
=构建依赖=
Line 307: Line 328:
There is a ruby translation of [http://developer.kde.org/language-bindings/ruby/tutorial/tutorial.html Qt Tutorial #1], and the corresponding ruby code is in qtruby/rubylib/tutorial/t1 to t14.
There is a ruby translation of [http://developer.kde.org/language-bindings/ruby/tutorial/tutorial.html Qt Tutorial #1], and the corresponding ruby code is in qtruby/rubylib/tutorial/t1 to t14.


And a Qt4 version of the same tutorial translated to Ruby by Darshan Ishaya [http://www.darshancomputing.com/qt4-qtruby-tutorial/ Qt4 Tutorial #1]  
相同的教学的Qt4版本,由 Darshan Ishaya 翻译为 Ruby,[[Development/Tutorials/Qt4_Ruby_Tutorial_(zh_CN)|Qt4 Ruby 教学]]


[http://developer.kde.org/language-bindings/ruby/tutorial2/tutorial2.html Qt Tutorial #2], a Charting Application with ruby code in qtruby/rubylib/examples/qt-examples/chart.
[http://developer.kde.org/language-bindings/ruby/tutorial2/tutorial2.html Qt Tutorial #2], a Charting Application with ruby code in qtruby/rubylib/examples/qt-examples/chart.

Latest revision as of 13:03, 23 June 2013

Template:I18n/Language Navigation Bar (zh CN)

非常完整的绑定包括 KDE API 和 Qt API。Korundum 套件包括 QtRuby,以及完整结合 Qt/KDE。QtRuby 套件仅包含 Qt 绑定并不相依 KDE。

Korundum/QtRuby - Ruby-KDE/Qt 绑定

Rapid GUI Development with QtRuby (使用Qt 3.x)已经出版。

作为基于 Smoke 的绑定,意味着他们提供完整存取大多数 KDE 4.x 和Qt 4.x类.

QtRuby

Hello world例子:

#!/usr/bin/ruby -w
require 'Qt4'
a = Qt::Application.new(ARGV)
hello = Qt::PushButton.new("Hello World!")
hello.resize(100, 30)
hello.show
a.exec

Hello Qt例子;更 'Rubyish'的方式:

require 'Qt4'

Qt::Application.new(ARGV) do
    Qt::Widget.new do

        self.window_title = 'Hello QtRuby v1.0'
        resize(200, 100)
    
        button = Qt::PushButton.new('Quit') do
            connect(SIGNAL :clicked) { Qt::Application.instance.quit }
        end

        label = Qt::Label.new('<big>Hello Qt in the Ruby way!</big>')
        
        self.layout = Qt::VBoxLayout.new do
            add_widget(label, 0, Qt::AlignCenter)
            add_widget(button, 0, Qt::AlignRight)
        end
        
        show
    end
    
    exec
end

当前 API覆盖率一览

可用调用

你可以呼叫 Qt 所有的公用(public)和保护(protected)方法,以及所有 friend 方法,如bitBlt() 等

虚方法

所有的虚拟方法都可以被覆盖,不仅仅是事件处理

配置属性

「foobar = 5」是「setFooBar(5)」的同义词

使用 CamelCase 或小写加底线的名称都可以

在方法的命名中任何底线被取消,而接续的字符大写化。例如,您可以使用这两种形式来呼叫相同的方法:

create_standard_status_bar_action()
createStandardStatusBarAction()

操作符重载

Qt 所有的操作符方法皆可用,例如:

p1 = Qt::Point.new(5,5)   => (5, 5)
p2 = Qt::Point.new(20,20) => (20, 20)
p1 + p2                   => (25, 25)

声明信号和槽(Signals和Slot)

讯号和槽宣告为如下的字符串列表:

slots 'setColor(QColor)', 'slotLoad(const QString&)'..
signals 'clicked()'..

对于槽和不带参数讯号,你可以使用 Ruby 符号:

slots :slotLoad
signals :clicked

Currently C++ type signatures must be used, a future version of QtRuby will allow ruby type signatures instead.

像这样连接(connect)槽和讯号:

Qt::Object.connect( @colormenu, SIGNAL( "activated(int)" ),
                  self, SLOT( "slotColorMenu(int)" ) )

There is also two another possibilities:

connect(:mysig, mytarget, :mymethod))
connect(SIGNAL('mysignal(int)'), mytarget, :mymethod))

或者,您可以连接讯号到区块:

quit_button.connect(SIGNAL :clicked) { $qApp.quit }

和这样发出(emit)讯号:

emit colorChanged( black )

构造器

你可以用普通风格呼叫建构子:

      quit = Qt::PushButton.new("Quit", self, "quit")

或者,您可以传递区块,如果你喜欢的话:

      w = MyWidget.new { setCaption("foobar") }

The block will be called in the context of the newly created instance.

Ordinary arguments can be provided as well as a block at the end:

      w = MyWidget.new(nil) { setCaption("foobar") }

They are run in the context of the new instance.

And there's more! You can also pass an arg to the block, and it will be run in the context of the arg:

      w = MyWidget.new { |theWidget| theWidget.setCaption "foobar" }

垃圾回收

当 ruby 实例垃圾回收时,如果不是被父对象「拥有」,基本的 C++ 实例只会删除。通常这会「正常运作」,但有时您需要在垃圾回收之前删除 C++,不管它是否有父亲。使用 dispose()、isDisposed() 和 disposed? 方法像是这样:

      item2.dispose
      if item2.disposed?
      	puts "item2 is disposed"
      end

C++ 'int*' 和 'int&' 参数类型

Ruby passes numeric values by value, and so they can't be changed when passed to a method. The Qt::Integer class provides a mutable numeric type which does get updated when passed as an argument. For example, this C++ method 'findByFileContent()':

      # static Ptr findByFileContent( const QString &fileName, 
      #                               int *accuracy=0 );

      acc = Qt::Integer.new(0)
      fc = KDE::MimeType.findByFileContent("mimetype.rb", acc)

It supports the arithmetic operators, and so expressions such as 'acc + 3' will work.

C++ 'bool*' 和 'bool&' 参数类型

There is a similar problem for bool arg types, and the mutable Qt::Boolean class can be used like this:

      # QFont getFont(bool * ok, const QFont&initial, 
      #               QWidget* parent = 0, const char *name = 0);		
		
      ok = Qt::Boolean.new
      font = Qt::FontDialog.getFont(ok, 
                          Qt::Font.new("Helvetica [Cronyx]", 10), 
                          self)
      if !ok.nil? 
      	# font is set to the font the user selected
      else 
      	# the user canceled the dialog
      end

Use 'nil?' to test the value returned in the Boolean

C++ (const )(unsigned )char* 参数类型

In some cases Qt/KDE object "takes ownership" over Ruby String passed as char* argument type. Programmer needs to make sure that Ruby String is not being garbage collected or changed for the time it's being used by Qt/KDE object. It is also quite possible that Qt/KDE object will change and eventually free it(memory used internally by Ruby String to store its data). Be very careful when you call this kind of methods and make sure that there is no overloaded version witch accepts QString or QByteArray first!

C++ unsigned char* functions

Very few functions (as QImage::bits()) return a uchar* to directly manipulate data. These functions are not supported in Ruby and will throw an ArgumentError. More information on the mail list.

调试

If a method call can't be matched in the Smoke library giving a 'method_missing' error, you can turn on debugging to trace the matching process:

      a = Qt::Application.new(ARGV)
      Qt.debug_level = Qt::DebugLevel::High
      a.loadLibrary("foo")  # Non existent method

Will give the following output:

      classname    == QApplication
      :: method == loadLibrary$
      -> methodIds == []
      candidate list:
      Possible prototypes:
          static QWidget* QApplication::widgetAt(int, int, bool)
			...

Here, the list of candidate methods 'methodIds' is empty

Another debugging mechanism allows various trace 'channels' to be switched on.

You can trace virtual method callbacks:

      Qt::Internal::setDebug(Qt::QtDebugChannel::QTDB_VIRTUAL)

Or trace QtRuby garbage collection:

      Qt::Internal::setDebug(Qt::QtDebugChannel::QTDB_GC)

字符串国际化

QtRuby 支持'u'、'e' 和 's' 的 $KCODE 值或命令行的对应 '-K'选项。Qt Designer .ui 文件有 UTF-8 字符串,因此,如果您要使用任何8位的 UTF - 8 字符,您将需要设定 $KCODE='u' 或使用 -Ku命令行选项。

其他功能和产品

Qt Designer

「rbuic4」工具包含在qtruby/tools/rbuic,用于编译 .ui 檔加入到 Ruby 程序代码中。如上所述,Qt Designer 使用UTF-8。除了原始的 uic C++ 实用工具的选项还要加上 '-x' 标签。This will generate a top level stub in the code:

      $ rbuic mainform.ui -x -o mainform.rb

Will add this to the end of the generated code:

      if $0 == __FILE__
          a = Qt::Application.new(ARGV)
          w = MainForm.new
          w.show
          a.exec
      end

Then you can test the example code straight away:

      $ ruby mainform.rb

Use the '-kde' option to require the 'korundum4' extension rather than the 'Qt4' one. If the '-x' option is used in conjunction, it generates a KDE top level. For example:

      $ rbuic4 -x -kde knotifywidgetbase.ui -o knotifywidgetbase.rb

Will generate this top level code:

      if $0 == __FILE__
      	about = KDE::AboutData.new("knotifywidgetbase", 
		                           "KNotifyWidgetBase", "0.1")
      	KDE::CmdLineArgs.init(ARGV, about)
        a = KDE::Application.new()
    	w = KNotifyWidgetBase.new
    	w.show
    	a.exec
      end

Qt::UILoader运行时加载.ui文件

You can load a Qt Designer .ui file at runtime with the 'quiloader' extension, for example:

      require 'Qt4'
      require 'quiloader'

      a = Qt::Application.new(ARGV)
      if ARGV.length == 0
        exit
      end

      if ARGV.length == 2
        QUI::WidgetFactory.loadImages ARGV[0]
        w = QUI::WidgetFactory.create ARGV[1]
        if w.nil?
          exit
        end
        w.show()
        a.connect(a, SIGNAL('lastWindowClosed()'), a, SLOT('quit()'))
        a.exec()
      end

API参考

使用 bin/rbqtapi 工具,以了解 QtRuby api 提供哪些方法。指令:

	  $ rbqtapi Qt::TextEdit

将列出 Qt::TextEdit 类别中所有的方法

	  $ rbqtapi -rsetCaption 

列出所有名称包含字符串'setCaption'的方法

例子

入门 QtRuby 程序设计的最佳方式是看一些现有的程序代码,并开始弄乱它。在 qtrubyexamples 和 korundum/examples 中有各式各样例子。

KDE相关信息

KDE 程序不是用

require 'Qt4'

,而是用

require 'korundum4'

KDE 的 K* 类别,例如 KApplication 被重命名为 KDE::Application。其他的 KDE 类别在KParts::、KIO:: 或 DOM:: 名称空间(namespaces)中,使用相同的名称在它们的 C++ 对应。

在命令行使用「rbkdeapi」脚本来查阅 Korundum api。例如:

      $ rbkdeapi KDE::Action

将列出在 KDE::Action 类别中所有的方法。There are currently (as at KDE 3.3 beta 2) 977 classes/30841 methods in the Smoke library runtime, so the coverage of the Qt/KDE api is pretty complete.

构建依赖

  • ruby 1.8 或更高版本 (svn trunk works with 1.9.1)
  • cmake 2.6 或更高版本
  • Qt 4.0 或更高版本
  • KDE 4.1 或更高版本(korundum 需要)

教程

There is a ruby translation of Qt Tutorial #1, and the corresponding ruby code is in qtruby/rubylib/tutorial/t1 to t14.

相同的教学的Qt4版本,由 Darshan Ishaya 翻译为 Ruby,Qt4 Ruby 教学

Qt Tutorial #2, a Charting Application with ruby code in qtruby/rubylib/examples/qt-examples/chart.

The Qt Designer Color Tool Tutorial, with ruby code in qtruby/rubylib/designer/examples/colortool.

Paul Lutus has written a tutorial on how to get started with Ruby GUI programming with Qt

For KDE, there is a ruby translation of this KDE 3.0 tutorial originally written for C++ by Antonio Larrosa Jiménez. The sources are in korundum/rubylib/tutorials/p1 to p9.

The book Rapid GUI Development with QtRuby is now available.

下载

您可以从 RubyForge 的QtRuby/Korundum 网站取得最新的 SVN 快照。

更多帮助

FreeNode有两个 IRC 频道(#qtruby and #kde-ruby)。如果你偏好电子邮件,您可以使用 kde-bindings 邮件列表(低流量),或者在 ruby-talk 邮件列表提问(您可以使用 Ruby 论坛 gateway,从网页发表文章到 ruby-talk)。

更多信息

ruby Qt 的系列文章(灵感来自dradis项目的工作):