ZetCode Ruby Qt Tutorial

Embed Size (px)

Citation preview

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    1/64

    ZetCode Ruby Qt tutorial

    This is Ruby Qt tutorial. In this tutorial you will learn the basics of GUI programming in Qt

    with Ruby language. The tutorial is suitable for beginners and intermediate programmers.

    Qt

    Qt is a cross-platform application development framework. ome of the well known

    applications developed with Qt are !"#$ %pera$ Google #arth and kype. Qt was first

    publicly released on &ay '((). It is dual licensed. That means$ it can be used for creating

    open source applications as well as commercial ones. Qt toolkit is a very powerful toolkit. It

    is well established in the open source community.

    Introduction to Ruby Qt

    In this part of the Ruby Qt tutorial$ we will introduce the Qt toolkit and create our first

    programs using the Ruby programming language.

    The purpose of this tutorial is to get you started with the Qt toolkit with the Ruby language.

    Images used in this tutorial can be downloadedhere.I used some icons from the tango icons

    pack of the Gnome pro*ect.

    About

    Qt is one of the leading toolkits for creating graphical user interfaces. Ruby is a popularscripting language.

    Creating a Tooltip

    The first e+ample will show a tooltip. , tooltip is a small rectangular window$ which gives a

    brief information about an ob*ect. It is usually a GUI component. It is part of the help system

    of the application.

    #!/usr/bin/ruby

    # ZetCode Ruby Qt tutorial## This code shows a tooltip on# a window.## author: Jan Bodnar# website: www.zetcode.co# last odiied: "epteber $%

    re&uire 'Qt'

    class Qt(pp ) Qt::*id+et

    de initialize

    '

    http://zetcode.com/img/gui/qtruby/images.ziphttp://zetcode.com/img/gui/qtruby/images.ziphttp://zetcode.com/img/gui/qtruby/images.ziphttp://zetcode.com/img/gui/qtruby/images.zip
  • 8/13/2019 ZetCode Ruby Qt Tutorial

    2/64

    super

    set*indowTitle ,Tooltip,

    setToolTip ,This is Qt::*id+et,

    resize -$ %-$ oe 0$$ 0$$

    show endend

    app 1 Qt::(pplication.new (R23Qt(pp.newapp.e4ec

    The e+ample creates a window. If we hover a mouse pointer over the area of the window$ a

    tooltip pops up.

    re&uire 'Qt'

    The re&uirekeyword imports necessery types that we will use in the application.

    class Qt(pp ) Qt::*id+et

    The e+ample inherits from a Qt::*id+et. The idget class is the base class of all user

    interface ob*ects. The widget is the atom of the user interface. It receives mouse$ keyboard

    and other events from the window system.

    set*indowTitle ,Tooltip,

    This method call creates a title for the window.

    setToolTip ,This is Qt::*id+et,

    The setToolTipmethod creates a tooltip for the idget ob*ect.

    resize -$ %-$

    ere we set the width and the height of the window.

    oe 0$$ 0$$

    The oemethod moves the window on the screen.

    show

    hen everything is ready$ we show the window on the screen.

    app 1 Qt::(pplication.new (R23Qt(pp.new

    app.e4ec

    /

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    3/64

    These three lines set up the application.

    0igure1 Tooltip

    Centering a window

    In the second e+ample$ we will center the window on the screen.

    #!/usr/bin/ruby

    # ZetCode Ruby Qt tutorial## This pro+ra centers a window# on the screen.## author: Jan Bodnar# website: www.zetcode.co# last odiied: "epteber $%

    re&uire 'Qt'

    *56T7 1 -$78527T 1 %-$

    class Qt(pp ) Qt::*id+et

    de initialize super

    set*indowTitle ,Center, resize *56T7 78527T

    center show end

    de center &dw 1 Qt::6es9top*id+et.new

    screen*idth 1 &dw.width screen7ei+ht 1 &dw.hei+ht

    4 1 screen*idth ; *56T7< / y 1 screen7ei+ht ; 78527T< /

    oe 4 y endend

    2

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    4/64

    app 1 Qt::(pplication.new (R23Qt(pp.newapp.e4ec

    The Qt toolkit does not have a single method to center a window.

    *56T7 1 -$78527T 1 %-$

    These two constants define the width and height of the application window.

    &dw 1 Qt::6es9top*id+et.new

    The Qt::6es9top*id+etclass provides information about the screen.

    screen*idth 1 &dw.width

    screen7ei+ht 1 &dw.hei+ht

    ere we determine the screen width and height.

    4 1 screen*idth ; *56T7< / y 1 screen7ei+ht ; 78527T< /

    ere we calculate the +$ y coordinates of the centered window. To center a window on the

    screen$ we need to know the si3e of the screen and the si3e of the window.

    oe 4 y

    e move the window to the computed +$ y coordinates.

    Quit button

    In the last e+ample of this section$ we will create a 4uit button. hen we press this button$

    the application terminates.

    #!/usr/bin/ruby

    # ZetCode Ruby Qt tutorial#

    # This pro+ra creates a &uit# button. *hen we press the button# the application terinates.## author: Jan Bodnar# website: www.zetcode.co# last odiied: "epteber $%

    re&uire 'Qt'

    class Qt(pp ) Qt::*id+et

    de initialize

    5

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    5/64

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    6/64

    0igure1 Quit button

    This section was an introduction to the Qt toolkit with the Ruby language.

    Layout management

    In this part of the Ruby Qt programming tutorial$ we will introduce layout managers.

    hen we design the GUI of our application$ we decide what components we will use and

    how we will organi3e those components in the application. To organi3e our components$ we

    use speciali3ed non visible ob*ects called layout managers. There are several options in Qt.

    e can use absolute positioning$ built-in layout managers or create a custom layout manager.

    e can also visually build the layouts using the Qt "esigner.

    Qt has some important built-in layout managers. The Qt::3Bo4Aayoutclass lines up widgets

    vertically. Qt::7Bo4Aayoutlines up widgets hori3ontally. The Qt::2ridAayoutclass lays

    out widgets in a grid. The grid layout is the most fle+ible layout manager. The bo+ layoutscan be nested into one another to create comple+ layouts.

    Absolute positioning

    In most cases$ programmers should use layout managers. There are a few situations$ where

    we can use absolute positioning. In absolute positioning$ the programmer specifies the

    position and the si3e of each widget in pi+els. The si3e and the position of a widget do not

    change$ if you resi3e a window. ,pplications look different on various platforms$ and what

    looks %! on 6inu+$ might not look %! on &ac. 7hanging fonts in your application might

    spoil the layout. If you translate your application into another language$ you must redo yourlayout. 0or all these issues$ use the absolute positioning only when you have a reason to do

    so.

    #!/usr/bin/ruby

    # ZetCode Ruby Qt tutorial## 5n this pro+ra we lay out wid+ets# usin+ absolute positionin+.## author: Jan Bodnar# website: www.zetcode.co

    # last odiied: "epteber $%

    8

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    7/64

    re&uire 'Qt'

    class Qt(pp ) Qt::*id+et

    de initialize super

    set*indowTitle ,(bsolute,

    init=ui

    resize 0$$ ?$ oe 0$$ 0$$

    show end

    de init=uiset"tyle"heet ,Q*id+et D bac9+round;color: #E%E%E% F,

    bardeGo 1 Qt::>i4ap.new ,bardeGo.Gp+, rotunda 1 Qt::>i4ap.new ,rotunda.Gp+, incol 1 Qt::>i4ap.new ,incol.Gp+,

    barAabel 1 Qt::Aabel.new sel barAabel.set>i4ap bardeGo barAabel.oe $ $

    rotAabel 1 Qt::Aabel.new sel

    rotAabel.set>i4ap rotunda rotAabel.oe E$ %H$

    inAabel 1 Qt::Aabel.new sel inAabel.set>i4ap incol inAabel.oe %I$ -$

    endend

    app 1 Qt::(pplication.new (R23Qt(pp.newapp.e4ec

    In this e+ample$ we show three images using the absolute positioning.

    barAabel 1 Qt::Aabel.new selbarAabel.set>i4ap bardeGo

    The Qt::Aabelwidget is used to hold the image.

    barAabel.oe $ $

    e use the oemethod to position the label on the window at +9/:$ y9/:.

    hen we resi3e the window$ the labels retain their initial si3e.

    ;

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    8/64

    0igure1 ,bsolute positioning

    Buttons example

    In the following e+ample$ we will position two buttons in the bottom right corner of the

    window.

    #!/usr/bin/ruby

    # ZetCode Ruby Qt tutorial## 5n this pro+ra we use bo4 layouts# to position two buttons in the# botto ri+ht corner o the window.## author: Jan Bodnar# website: www.zetcode.co# last odiied: "epteber $%

    re&uire 'Qt'

    class Qt(pp ) Qt::*id+et

    de initialize super

    set*indowTitle ,Buttons,

    init=ui

    resize 00$ %I$ oe 0$$ 0$$

    show end

    de init=ui bo4 1 Qt::3Bo4Aayout.new sel

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    9/64

    hbo4 1 Qt::7Bo4Aayout.new

    o9 1 Qt::>ushButton.new ,, sel apply 1 Qt::>ushButton.new ,(pply, sel

    hbo4.add*id+et o9 % Qt::(li+nRi+ht

    hbo4.add*id+et apply

    bo4.add"tretch % bo4.addAayout hbo4 endend

    app 1 Qt::(pplication.new (R23Qt(pp.newapp.e4ec

    e use nested bo+ layouts to get our intended layout.

    bo4 1 Qt::3Bo4Aayout.new selhbo4 1 Qt::7Bo4Aayout.new

    e use one vertical and one hori3ontal bo+.

    o9 1 Qt::>ushButton.new ,, selapply 1 Qt::>ushButton.new ,(pply, sel

    These are the two buttons that will go into the bottom right corner of the window.

    hbo4.add*id+et o9 % Qt::(li+nRi+ht

    e put the ok button into the hori3ontal bo+. The second parameter is the stretchfactor. It

    e+pands the area allotted to the ok button. It takes all available space left. The alignment of

    the windget inside this area is controlled by the third parameter. The Qt::(li+nRi+htwill

    align the button to the right.

    bo4.add"tretch %

    This line creates a vertically e+panded white space$ which will push the hori3ontal bo+ with

    the buttons to the bottom.

    bo4.addAayout hbo4

    The hori3ontal bo+ is nested into the vertical bo+.

    (

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    10/64

    0igure1 =uttons e+ample

    Windows example

    The following is a more complicated e+ample with nested bo+ layouts.

    #!/usr/bin/ruby

    # ZetCode Ruby Qt tutorial## 5n this pro+ra use bo4 layouts# to create a *indows e4aple## author: Jan Bodnar# website: www.zetcode.co# last odiied: "epteber $%

    re&uire 'Qt'

    class Qt(pp ) Qt::*id+et

    de initialize super

    set*indowTitle ,*indows,

    init=ui

    resize 0-$ 0$$ oe 0$$ 0$$

    show end

    de init=ui bo4 1 Qt::3Bo4Aayout.new sel

    bo4% 1 Qt::3Bo4Aayout.new hbo4% 1 Qt::7Bo4Aayout.new hbo4 1 Qt::7Bo4Aayout.new

    windAabel 1 Qt::Aabel.new ,*indows, sel edit 1 Qt::Te4t8dit.new sel

    edit.set8nabled alse

    actiate 1 Qt::>ushButton.new ,(ctiate, sel

    ':

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    11/64

    close 1 Qt::>ushButton.new ,Close, sel help 1 Qt::>ushButton.new ,7elp, sel o9 1 Qt::>ushButton.new ,, sel

    bo4.add*id+et windAabel

    bo4%.add*id+et actiate bo4%.add*id+et close $ Qt::(li+nTop hbo4%.add*id+et edit hbo4%.addAayout bo4%

    bo4.addAayout hbo4%

    hbo4.add*id+et help hbo4.add"tretch % hbo4.add*id+et o9

    bo4.addAayout hbo4 % setAayout bo4

    endend

    app 1 Qt::(pplication.new (R23Qt(pp.newapp.e4ec

    In this layout$ we use two vertical and hori3ontal bo+es.

    bo4 1 Qt::3Bo4Aayout.new sel

    This is the base layout of the e+ample.

    windAabel 1 Qt::Aabel.new ,*indows, sel

    0irst goes the label widget. It goes simply to the top of the vertical bo+.

    bo4%.add*id+et actiatebo4%.add*id+et close $ Qt::(li+nTophbo4%.add*id+et edithbo4%.addAayout bo4%

    bo4.addAayout hbo4%

    In the center part of the window we have a te+t edit widget and two vertically lined up

    buttons. The buttons go into a vertical bo+. The buttons are aligned to the top within this

    vertical bo+. The vertical bo+ and the te+t edit go into a hori3ontal bo+. This hori3ontal bo+

    goes to the base vertical bo+$ *ust below the label widget.

    hbo4.add*id+et helphbo4.add"tretch %hbo4.add*id+et o9

    bo4.addAayout hbo4 %

    The help and the ok button go into another hori3ontal bo+. There is an e+panded white spacebetween these two buttons. ,gain$ the hori3ontal bo+ goes to the base vertical bo+.

    ''

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    12/64

    setAayout bo4

    The base vertical bo+ is set to be the main layout of the window.

    0igure1 indows e+ample

    New Folder example

    In the last e+ample$ we use the Qt::2ridAayoutmanager to create a >ew 0older layout

    e+ample.

    #!/usr/bin/ruby

    # ZetCode Ruby Qt tutorial## 5n this pro+ra use the 2ridAayout# to create a @ew Kolder e4aple.## author: Jan Bodnar# website: www.zetcode.co# last odiied: "epteber $%

    re&uire 'Qt'

    class Qt(pp ) Qt::*id+et

    de initialize super

    set*indowTitle ,@ew Kolder,

    init=ui

    resize 0$$ 0$$

    oe 0$$ 0$$

    '/

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    13/64

    show end

    de init=ui

    +rid 1 Qt::2ridAayout.new sel

    naeAabel 1 Qt::Aabel.new ,@ae, sel nae8dit 1 Qt::Aine8dit.new sel te4t 1 Qt::Te4t8dit.new sel o9Button 1 Qt::>ushButton.new ,, sel closeButton 1 Qt::>ushButton.new ,Close, sel

    +rid.add*id+et naeAabel $ $ +rid.add*id+et nae8dit $ % % 0 +rid.add*id+et te4t % $ E +rid.setColun"tretch % % +rid.add*id+et o9Button E +rid.add*id+et closeButton E 0

    endend

    app 1 Qt::(pplication.new(R23ushButton.new ,Blue, sel blueb.setChec9able true blueb.oe %$ %%$

    connect blueb "52@(A,clic9ed

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    22/64

    s&uare 1 Qt::*id+et.new sels&uare.set2eoetry %-$ $ %$$ %$$s&uare.set"tyle"heet ,Q*id+et D bac9+round;color: s F, color.nae

    e create a s4uare widget. e set its si3e. ,t the beginning$ it is black. In Qt$ we use style

    sheets to customi3e the appearance of a widget.

    Inside the on=clic9edmethod$ we determine the colour value and update the s4uare widget

    to a new colour.

    red 1 color.red+reen 1 color.+reenblue 1 color.blue

    ere we determine the current colour of the s4uare widget.

    i redb.isChec9ed

    red 1 --else

    red 1 $end

    The red part of the colour is changed$ depending on the state of the red toggle button.

    color 1 Qt::Color.new red +reen blue

    e create a new colour value.

    s&uare.set"tyle"heet,Q*id+et D bac9+round;color: s F, color.nae(C5TL 1 I$$M(=C(>(C5TL 1 I-$

    class Burnin+ ) Qt::*id+et

    de initializeparentainter.new sel

    draw*id+et painter

    painter.end end

    de draw*id+et painter

    w 1 width.to=

    slid=width 1 parent.+etCurrent*idth

    step 1 w / 6535"5@"(C5TL< W slid=width(C5TL< W KSAA=C(>(C5TL(C5TL painter.set>en yellowColor painter.setBrush Qt::Brush.new yellowColor painter.drawRect Qt::RectK.new $ $ ull >(@8A=78527T painter.set>en redColor painter.setBrush Qt::Brush.new redColor painter.drawRect Qt::RectK.new ullU% $ till;ull>(@8A=78527T else

    i slid=width V $ painter.set>en yellowColor painter.setBrush Qt::Brush.new yellowColor painter.drawRect Qt::RectK.new $ $ till >(@8A=78527T end

    )2

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    54/64

    end

    painter.set>en Qt::Color.new P$ P$ P$ painter.setBrush Qt::@oBrush painter.drawRect $ $ w;% >(@8A=78527T;%

    newKont 1 ont newKont.set>oint"ize I painter.setKont newKont

    or i in %..nu.len+th< painter.drawAine Qt::AineK.new iWstep % iWstep A5@8=*56T7

    etrics 1 Qt::KontMetrics.new newKont

    w 1 etrics.width nuXi;%Y painter.drawTe4tQt::>ointK.newiWstep;w/ 65"T(@C8

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    55/64

    de onChan+ed al cur=width 1 al wid+et.repaint end

    de +etCurrent*idth return cur=width endend

    app 1 Qt::(pplication.new (R23Qt(pp.newapp.e4ec

    In this file$ we create the =urning widget.

    class Burnin+ ) Qt::*id+et

    The custom widget is based on the *id+etwidget.

    >(@8A=78527T 1 0$65"T(@C8 1 %PA5@8=*56T7 1 -6535"5@" 1 %$KSAA=C(>(C5TL 1 I$$M(=C(>(C5TL 1 I-$

    These are important constants. The >(@8A=78527Tdefines the height for the custom widget.

    The 65"T(@C8is the distance of the numbers on the scale from the top of their parent border.The A5@8=*56T7is the vertical line width. The 6535"5@"is the number of parts of the scale.

    The KSAA=C(>(C5TLis the ma+imum capacity of the media. ,fter it is reached$ overburning

    happens. This is visuali3ed by a red color. The M(=C(>(C5TLis the ma+imum capacity of a

    medium.

    nu 1 X ,I-, ,%-$, ,-, ,0$$,,0I-, ,E-$, ,--, ,H$$, ,HI-, Y

    e use these numbers to build the scale of the =urning widget.

    de paint8ent eent

    painter 1 Qt::>ainter.new sel

    draw*id+et painter painter.endend

    The drawing of the custom widget is delegated to the draw*id+etmethod.

    slid=width 1 parent.+etCurrent*idth

    e use it to get the currently selected slider value.

    w 1 width.to=

    ))

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    56/64

    e get the width of the widget. The width of the custom widget is dynamic. It can be resi3ed

    by a user.

    till 1 w / M(=C(>(C5TL< W slid=width(C5TL< W KSAA=C(>(C5TLote that we use floating point values. e get greater precision in

    drawing.

    painter.set>en redColorpainter.setBrush Qt::Brush.new redColorpainter.drawRect Qt::RectK.new ullU% $ till;ull >(@8A=78527T

    These three lines draw the red rectangle$ indicating the overburning.

    painter.drawRect $ $ w;% >(@8A=78527T;%

    This is the perimeter of the widget. The outside rectangle.

    painter.drawAine Qt::AineK.new iWstep % iWstep A5@8=*56T7

    ere we draw the small vertical lines.

    w 1 etrics.width nuXi;%Ypainter.drawTe4tQt::>ointK.newiWstep;w/ 65"T(@C8

  • 8/13/2019 ZetCode Ruby Qt Tutorial

    57/64

    0igure1 The =urning widget

    In this part of the Ruby Qt tutorial$ we have demonstrated how to create a custom widget.

    Nibbles

    In this part of the Ruby Qt programming tutorial$ we will create a >ibbles game clone.

    Nibblesis an older classic video game. It was first created in late ;:s. 6ater it was brought to

    A7s. In this game the player controls a snake. The ob*ective is to eat as many apples as

    possible. #ach time the snake eats an apple$ its body grows. The snake must avoid the walls

    and its own body.

    &e(elopment

    The si3e of each of the *oints of a snake is ':p+. The snake is controlled with the cursor keys.

    Initially$ the snake has three *oints. The game starts immediately. hen the game is finished$

    we display Game %ver message in the center of the window.

    =oard.rb*56T7 1 0$$78527T 1 0$$6T="5Z8 1 %$(AA=6T" 1 *56T7 W 78527T / 6T="5Z8 W 6T="5Z8" 1 P

    68A(L 1 %E$

    4 1 X$Y W (AA=6T"y 1 X$Y W (AA=6T"

    class Board ) Qt::*id+et

    de initializeparent