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

    From KDE TechBase
    No edit summary
    m (AnneW moved page Development/Languages/Ruby (zh TW) to Archive:Development/Languages/Ruby (zh TW) 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_TW)|Development/Languages/Ruby}}
    [[Image:ruby.png]]
    [[Image:ruby.png]]


    Line 12: Line 12:
    = 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>


    更'Rubyish'方式的 Hello Qt 範例:
    更'Rubyish'方式的 Hello Qt 範例:


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


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


    = 目前 API 範圍概覽 =
    = 目前 API 範圍概覽 =
    Line 63: Line 62:


    ==使用 CamelCase 或小寫加底線的名稱都可以==
    ==使用 CamelCase 或小寫加底線的名稱都可以==
    在方法的命名中任何底線被取消,而接續的字元大寫化。例如,您可以使用這兩種形式來呼叫相同的方法:


    在方法的命名中任何底線被取消,而接續的字元大寫化。例如,您可以使用這兩種形式來呼叫相同的方法:
    <syntaxhighlight lang="ruby">
          create_standard_status_bar_action()
    create_standard_status_bar_action()
          createStandardStatusBarAction()
    createStandardStatusBarAction()
    </syntaxhighlight>


    ==運算子重載==
    ==運算子重載==
    Qt 所有的運算子方法皆可用,例如:
    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)和槽(Slots)==
    ==宣告訊號(Signals)和槽(Slots)==
    訊號和槽宣告為如下的字串列表:
    訊號和槽宣告為如下的字串列表:


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


    對於槽和不帶參數訊號,你可以使用 Ruby 符號:
    對於槽和不帶參數訊號,你可以使用 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.
    Line 92: Line 97:
    像這樣連接(connect)槽和訊號:
    像這樣連接(connect)槽和訊號:


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


    或者,您可以連接訊號到區塊:
    或者,您可以連接訊號到區塊:


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


    和這樣發出(emit)訊號:
    和這樣發出(emit)訊號:


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


    ==建構子==
    ==建構子==
    你可以用普通風格呼叫建構子:
    你可以用普通風格呼叫建構子:


          quit = Qt::PushButton.new("Quit", self, "quit")
    <syntaxhighlight lang="ruby">
    quit = Qt::PushButton.new("Quit", self, "quit")
    </syntaxhighlight>


    或者,您可以傳遞區塊,如果你喜歡的話:
    或者,您可以傳遞區塊,如果你喜歡的話:


          w = MyWidget.new { setCaption("foobar") }
    <syntaxhighlight lang="ruby">
    w = MyWidget.new { setCaption("foobar") }
    </syntaxhighlight>


    The block will be called in the context of the newly created instance.
    The block will be called in the context of the newly created instance.
    Line 117: Line 131:
    Ordinary arguments can be provided as well as a block at the end:
    Ordinary arguments can be provided as well as a block at the end:


          w = MyWidget.new(nil) { setCaption("foobar") }
    <syntaxhighlight lang="ruby">
    w = MyWidget.new(nil) { setCaption("foobar") }
    </syntaxhighlight>


    They are run in the context of the new instance.
    They are run in the context of the new instance.
    Line 123: Line 139:
    And there's more! You can also pass an arg to the block, and it will be run in the context of the arg:
    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" }
    <syntaxhighlight lang="ruby">
    w = MyWidget.new { |theWidget| theWidget.setCaption "foobar" }
    </syntaxhighlight>


    ==垃圾回收==
    ==垃圾回收==
    Line 129: Line 147:
    當 ruby 實例垃圾回收時,如果不是被父物件「擁有」,基本的 C++ 實例只會刪除。通常這會「正常運作」,但有時您需要在垃圾回收之前刪除 C++,不管它是否有父親。使用 dispose()、isDisposed() 和 disposed? 方法像是這樣:
    當 ruby 實例垃圾回收時,如果不是被父物件「擁有」,基本的 C++ 實例只會刪除。通常這會「正常運作」,但有時您需要在垃圾回收之前刪除 C++,不管它是否有父親。使用 dispose()、isDisposed() 和 disposed? 方法像是這樣:


          item2.dispose
    <syntaxhighlight lang="ruby">
          if item2.disposed?
    item2.dispose
          puts "item2 is disposed"
    if item2.disposed?
          end
    puts "item2 is disposed"
    end
    </syntaxhighlight>


    ==C++ 'int*' 和 'int&' 參數型態==
    ==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()':
    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,  
    <syntaxhighlight lang="ruby">
          #                              int *accuracy=0 );
    # static Ptr findByFileContent( const QString &fileName,  
    #                              int *accuracy=0 );
          acc = Qt::Integer.new(0)
          fc = KDE::MimeType.findByFileContent("mimetype.rb", acc)
       
       
    acc = Qt::Integer.new(0)
    fc = KDE::MimeType.findByFileContent("mimetype.rb", acc)
    </syntaxhighlight>


    It supports the arithmetic operators, and so expressions such as 'acc + 3' will work.
    It supports the arithmetic operators, and so expressions such as 'acc + 3' will work.
    Line 151: Line 171:
    There is a similar problem for bool arg types, and the mutable Qt::Boolean class can be used like this:
    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,  
    <syntaxhighlight lang="ruby">
          #              QWidget* parent = 0, const char *name = 0);
    # QFont getFont(bool * ok, const QFont&initial,  
    #              QWidget* parent = 0, const char *name = 0);
     
     
          ok = Qt::Boolean.new
    ok = Qt::Boolean.new
          font = Qt::FontDialog.getFont(ok,  
    font = Qt::FontDialog.getFont(ok,  
                              Qt::Font.new("Helvetica [Cronyx]", 10),  
                        Qt::Font.new("Helvetica [Cronyx]", 10),  
                              self)
                        self)
          if !ok.nil?  
    if !ok.nil?  
          # font is set to the font the user selected
    # font is set to the font the user selected
          else  
    else  
          # the user canceled the dialog
    # the user canceled the dialog
          end
    end
    </syntaxhighlight>


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


    ==C++ (const )(unsigned )char* 參數型態==
    ==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!
    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* 函式==
    ==C++ unsigned char* 函式==
    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 [http://lists.kde.org/?l=kde-bindings&m=122899325331866&w=2 mail list].
    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 [http://lists.kde.org/?l=kde-bindings&m=122899325331866&w=2 mail list].


    ==除錯==
    ==除錯==
    If a method call can't be matched in the Smoke library giving a 'method_missing' error, first check that you are passing correct class instance that is properly initialized (with super method called in constructors of custom Qt classes descendants). You can also turn on debugging to trace the matching process:
    If a method call can't be matched in the Smoke library giving a 'method_missing' error, first check that you are passing correct class instance that is properly initialized (with super method called in constructors of custom Qt classes descendants). You can also turn on debugging to trace the matching process:


          a = Qt::Application.new(ARGV)
    <syntaxhighlight lang="ruby">
          Qt.debug_level = Qt::DebugLevel::High
    a = Qt::Application.new(ARGV)
          a.loadLibrary("foo")  # Non existent method
    Qt.debug_level = Qt::DebugLevel::High
    a.loadLibrary("foo")  # Non existent method
    </syntaxhighlight>


    Will give the following output:
    Will give the following output:
    Line 197: Line 218:
    You can trace virtual method callbacks:
    You can trace virtual method callbacks:


          Qt::Internal::setDebug(Qt::QtDebugChannel::QTDB_VIRTUAL)
    <syntaxhighlight lang="ruby">
    Qt::Internal::setDebug(Qt::QtDebugChannel::QTDB_VIRTUAL)
    </syntaxhighlight>


    Or trace QtRuby garbage collection:
    Or trace QtRuby garbage collection:


          Qt::Internal::setDebug(Qt::QtDebugChannel::QTDB_GC)
    <syntaxhighlight lang="ruby">
    Qt::Internal::setDebug(Qt::QtDebugChannel::QTDB_GC)
    </syntaxhighlight>


    ==字串 i18n==
    ==字串 i18n==
    QtRuby 支援'u'、'e' 和 's'  的 $KCODE 值或命令列的對應 '-K'選項。Qt Designer .ui 檔有 UTF-8 字串,因此,如果您要使用任何8位元的 UTF - 8 字元,您將需要設定 $KCODE='u' 或使用 -Ku命令列選項。
    QtRuby 支援'u'、'e' 和 's'  的 $KCODE 值或命令列的對應 '-K'選項。Qt Designer .ui 檔有 UTF-8 字串,因此,如果您要使用任何8位元的 UTF - 8 字元,您將需要設定 $KCODE='u' 或使用 -Ku命令列選項。


    Line 213: Line 237:
    「rbuic4」工具包含在qtruby/tools/rbuic,用於編譯 .ui 檔加入到 Ruby 程式碼中。如上所述,Qt Designer 使用UTF-8。除了原始的 uic C++ 實用工具的選項還要加上 '-x' 標簽。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
    <syntaxhighlight lang="bash">
    $ rbuic mainform.ui -x -o mainform.rb
    </syntaxhighlight>


    這將在生成程式碼的最後加上這個:
    這將在生成程式碼的最後加上這個:


          if $0 == __FILE__
    <syntaxhighlight lang="ruby">
              a = Qt::Application.new(ARGV)
    if $0 == __FILE__
              w = MainForm.new
        a = Qt::Application.new(ARGV)
              w.show
        w = MainForm.new
              a.exec
        w.show
          end
        a.exec
    end
    </syntaxhighlight>


    Then you can test the example code straight away:
    Then you can test the example code straight away:
    Line 230: Line 258:
    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:
    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
    <syntaxhighlight lang="bash">
    $ rbuic4 -x -kde knotifywidgetbase.ui -o knotifywidgetbase.rb
    </syntaxhighlight>


    Will generate this top level code:
    Will generate this top level code:


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


    ==Loading .ui files at runtime with Qt::UILoader==
    ==Loading .ui files at runtime with Qt::UILoader==
    Line 299: Line 331:
    使用 bin/rbqtapi 工具,以了解 QtRuby api 提供哪些方法。指令:
    使用 bin/rbqtapi 工具,以了解 QtRuby api 提供哪些方法。指令:


      $ rbqtapi Qt::TextEdit
    <syntaxhighlight lang="bash">
    $ rbqtapi Qt::TextEdit
    </syntaxhighlight>


    將列出 Qt::TextEdit 類別中所有的方法
    將列出 Qt::TextEdit 類別中所有的方法


      $ rbqtapi -rsetCaption  
    <syntaxhighlight lang="bash">
    $ rbqtapi -rsetCaption  
    </syntaxhighlight>


    列出所有名稱包含字串'setCaption'的方法
    列出所有名稱包含字串'setCaption'的方法
    Line 313: Line 349:
    =KDE 的特定資訊=
    =KDE 的特定資訊=


    KDE 程式不是用 <code>require 'Qt4'</code>,而是用 <code>require 'korundum4'</code>  
    KDE 程式不是用 <syntaxhighlight lang="ruby">require 'Qt4'</syntaxhighlight>,而是用 <syntaxhighlight lang="ruby">require 'korundum4'</syntaxhighlight>  


    KDE 的 K* 類別,例如 KApplication 被重命名為 KDE::Application。其他的 KDE 類別在KParts::、KIO:: 或 DOM:: 名稱空間(namespaces)中,使用相同的名稱在它們的 C++ 對應。
    KDE 的 K* 類別,例如 KApplication 被重命名為 KDE::Application。其他的 KDE 類別在KParts::、KIO:: 或 DOM:: 名稱空間(namespaces)中,使用相同的名稱在它們的 C++ 對應。
    Line 319: Line 355:
    在命令列使用「rbkdeapi」腳本來查閱 Korundum api。例如:
    在命令列使用「rbkdeapi」腳本來查閱 Korundum api。例如:


          $ rbkdeapi KDE::Action
    <syntaxhighlight lang="bash">
    $ rbkdeapi KDE::Action
    </syntaxhighlight>


    將列出在 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.
    將列出在 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 343: Line 381:


    The book [http://www.pragmaticprogrammer.com/titles/ctrubyqt/ Rapid GUI Development with QtRuby] is now available.
    The book [http://www.pragmaticprogrammer.com/titles/ctrubyqt/ Rapid GUI Development with QtRuby] is now available.
    There is also an approach to create an [[Development/Languages/Ruby/Ruby-Qt/KDE Book|Ruby-Qt/KDE Book]] under a free license. The content will be created in this wiki. The book made with latex will be derived from the content in the wiki. Any Questions? Contact [[User:SaLOUt|me]]!


    =下載=
    =下載=
    Line 348: Line 388:


    =更多協助=
    =更多協助=
    在[http://www.freenode.net FreeNode]有兩個 IRC 頻道(<tt><nowiki>#qtruby</nowiki></tt> 和 <tt><nowiki>#kde-ruby</nowiki></tt>)。如果你偏好電子郵件,您可以使用  [http://mail.kde.org/mailman/listinfo/kde-bindings kde-bindings 郵件列表](低流量),或者在 [http://www.ruby-lang.org/en/20020104.html ruby-talk] 郵件列表提問(您可以使用 [http://www.ruby-forum.com/ Ruby 論壇] gateway,從網頁發表文章到 ruby-talk)。
    在[http://www.freenode.net FreeNode]有兩個 IRC 頻道(<tt><nowiki>#qtruby</nowiki></tt> 和 <tt><nowiki>#kde-ruby</nowiki></tt>)。如果你偏好電子郵件,您可以使用  [http://mail.kde.org/mailman/listinfo/kde-bindings kde-bindings 郵件列表](低流量),或者在 [http://www.ruby-lang.org/en/20020104.html ruby-talk] 郵件列表提問(您可以使用 [http://www.ruby-forum.com/ Ruby 論壇] gateway,從網頁發表文章到 ruby-talk)。



    Latest revision as of 15:15, 23 June 2013

    Template:I18n/Language Navigation Bar (zh TW)

    非常完整的綁定包括 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
    

    更'Rubyish'方式的 Hello Qt 範例:

    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() 等

    虛擬(virtual)方法

    所有的虛擬方法都可以被覆蓋,不僅僅是事件處理

    屬性

    「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)和槽(Slots)

    訊號和槽宣告為如下的字串列表:

    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)" ) )
    

    或者,您可以連接訊號到區塊:

    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* 函式

    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, first check that you are passing correct class instance that is properly initialized (with super method called in constructors of custom Qt classes descendants). You can also 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)
    

    字串 i18n

    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
    

    這將在生成程式碼的最後加上這個:

    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
    

    Loading .ui files at runtime with Qt::UILoader

    Warning
    This section needs improvements: Please help us to

    cleanup confusing sections and fix sections which contain a todo


    Remove example that does not work

    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
    

    With new version API changed a little.

          require 'Qt4'
          require 'qtuitools'
    
          a = Qt::Application.new(ARGV)
          if ARGV.length == 0
            exit
          end
    
          if ARGV.length == 1
            file = Qt::File.new(ARGV[1])
            file.open(Qt::File::ReadOnly)
    
            loader = Qt::UiLoader.new
            window = loader.load(file, nil)
            file.close
    
            if (window.nil?)
              print "Error. Window is nil.\n"
              exit
            end
            window.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 需要)

    教學

    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.

    There is also an approach to create an Ruby-Qt/KDE Book under a free license. The content will be created in this wiki. The book made with latex will be derived from the content in the wiki. Any Questions? Contact me!

    下載

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

    更多協助

    FreeNode有兩個 IRC 頻道(#qtruby#kde-ruby)。如果你偏好電子郵件,您可以使用 kde-bindings 郵件列表(低流量),或者在 ruby-talk 郵件列表提問(您可以使用 Ruby 論壇 gateway,從網頁發表文章到 ruby-talk)。

    更多資訊

    ruby Qt 的系列文章(靈感來自dradis專案的工作):