Development/Tutorials/Qt4 Ruby Tutorial/Chapter 05: Difference between revisions
No edit summary |
No edit summary |
||
(8 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
<languages /> | |||
name=Building Blocks| | {{<translate><!--T:1--> | ||
TutorialBrowser</translate>| | |||
series=[[Special:myLanguage/Development/Tutorials/Qt4_Ruby_Tutorial|<translate><!--T:2--> | |||
Qt4 Ruby Tutorial</translate>]]| | |||
name=<translate><!--T:3--> | |||
Building Blocks</translate>| | |||
pre=[[Special:myLanguage/Development/Tutorials/Qt4_Ruby_Tutorial/Chapter_04|<translate><!--T:4--> | |||
Tutorial 4 - Let There Be Widget</translate>]]| | |||
next=[[Special:myLanguage/Development/Tutorials/Qt4_Ruby_Tutorial/Chapter_06|<translate><!--T:5--> | |||
Tutorial 6 - Building Blocks Galore!</translate>]] | |||
}} | |||
<translate> | |||
== Building Blocks == <!--T:6--> | |||
</translate> | |||
<translate> | |||
<!--T:7--> | |||
[[Image:Qt4_Ruby_Tutorial_Screenshot_5.png|center]] | |||
</translate> | |||
<translate> | |||
<!--T:8--> | |||
Files: | Files: | ||
</translate> | |||
* [http://www.darshancomputing.com/qt4-qtruby-tutorial/tutorial/t5/t5.rb t5.rb] | * [http://www.darshancomputing.com/qt4-qtruby-tutorial/tutorial/t5/t5.rb t5.rb] | ||
=== Overview === | <translate> | ||
=== Overview === <!--T:9--> | |||
This example shows how to create and connect together several widgets by using signals and slots, and how to handle resizes. | <!--T:10--> | ||
This example shows how to create and connect together several widgets by using signals and slots, and how to handle resizes. | |||
</translate> | |||
< | <syntaxhighlight lang="ruby"> | ||
require 'Qt4' | require 'Qt4' | ||
Line 26: | Line 42: | ||
def initialize() | def initialize() | ||
super() | super() | ||
quit = Qt::PushButton.new('Quit') | <translate><!--T:35--> | ||
quit = Qt::PushButton.new('Quit')</translate> | |||
quit.setFont(Qt::Font.new('Times', 18, Qt::Font::Bold)) | quit.setFont(Qt::Font.new('Times', 18, Qt::Font::Bold)) | ||
Line 52: | Line 69: | ||
widget.show() | widget.show() | ||
app.exec() | app.exec() | ||
</ | </syntaxhighlight> | ||
=== Line by Line Walkthrough === | <translate> | ||
< | === Line by Line Walkthrough === <!--T:19--> | ||
</translate> | |||
<syntaxhighlight lang="ruby"> | |||
lcd = Qt::LCDNumber.new(2) | lcd = Qt::LCDNumber.new(2) | ||
</ | </syntaxhighlight> | ||
<translate> | |||
<!--T:20--> | |||
'''<tt>lcd</tt>''' is a [http://doc.qt.nokia.com/latest/qlcdnumber.html Qt::LCDNumber], a widget that displays numbers in an LCD-like fashion. This instance is set up to display two digits. | '''<tt>lcd</tt>''' is a [http://doc.qt.nokia.com/latest/qlcdnumber.html Qt::LCDNumber], a widget that displays numbers in an LCD-like fashion. This instance is set up to display two digits. | ||
</translate> | |||
< | <syntaxhighlight lang="ruby"> | ||
slider = Qt::Slider.new(Qt::Horizontal) | slider = Qt::Slider.new(Qt::Horizontal) | ||
slider.setRange(0, 99) | slider.setRange(0, 99) | ||
slider.setValue(0) | slider.setValue(0) | ||
</ | </syntaxhighlight> | ||
<translate> | |||
<!--T:21--> | |||
The user can use the [http://doc.qt.nokia.com/latest/qslider.html Qt::Slider] widget to adjust an integer value in a range. Here we create a horizontal one, set its minimum value to 0, its maximum value to 99, and its initial value to 0. | The user can use the [http://doc.qt.nokia.com/latest/qslider.html Qt::Slider] widget to adjust an integer value in a range. Here we create a horizontal one, set its minimum value to 0, its maximum value to 99, and its initial value to 0. | ||
</translate> | |||
< | <syntaxhighlight lang="ruby"> | ||
connect(slider, SIGNAL('valueChanged(int)'), lcd, SLOT('display(int)')) | connect(slider, SIGNAL('valueChanged(int)'), lcd, SLOT('display(int)')) | ||
</ | </syntaxhighlight> | ||
<translate> | |||
<!--T:22--> | |||
Here we use the [http://doc.qt.nokia.com/latest/signalsandslots.html signals and slots] mechanism to connect the slider's [http://doc.qt.nokia.com/latest/qabstractslider.html#valueChanged QAbstractSlider::valueChanged()] signal to the LCD number's display() slot. | Here we use the [http://doc.qt.nokia.com/latest/signalsandslots.html signals and slots] mechanism to connect the slider's [http://doc.qt.nokia.com/latest/qabstractslider.html#valueChanged QAbstractSlider::valueChanged()] signal to the LCD number's display() slot. | ||
<!--T:23--> | |||
Whenever the slider's value changes it broadcasts the new value by emitting the [http://doc.qt.nokia.com/latest/qabstractslider.html#valueChanged QAbstractSlider::valueChanged()] signal. Because that signal is connected to the LCD number's [http://doc.qt.nokia.com/latest/qlcdnumber.html#intValue-prop QLCDNumber::display()] slot, the slot is called when the signal is broadcast. Neither of the objects knows about the other. This is essential in component programming. | Whenever the slider's value changes it broadcasts the new value by emitting the [http://doc.qt.nokia.com/latest/qabstractslider.html#valueChanged QAbstractSlider::valueChanged()] signal. Because that signal is connected to the LCD number's [http://doc.qt.nokia.com/latest/qlcdnumber.html#intValue-prop QLCDNumber::display()] slot, the slot is called when the signal is broadcast. Neither of the objects knows about the other. This is essential in component programming. | ||
</translate> | |||
< | <syntaxhighlight lang="ruby"> | ||
layout = Qt::VBoxLayout.new() | layout = Qt::VBoxLayout.new() | ||
layout.addWidget(quit) | layout.addWidget(quit) | ||
Line 83: | Line 112: | ||
layout.addWidget(slider) | layout.addWidget(slider) | ||
setLayout(layout) | setLayout(layout) | ||
</ | </syntaxhighlight> | ||
<translate> | |||
<!--T:24--> | |||
'''<tt>MyWidget</tt>''' now uses a [http://doc.qt.nokia.com/latest/qvboxlayout.html Qt::VBoxLayout] to manage the geometry of its child widgets. For that reason, we don't need to specify the screen coordinates for each widget like we did in Chapter 4. In addition, using a layout ensures that the child widgets are resized when the window is resized. Then we add the '''<tt>quit</tt>''', '''<tt>lcd</tt>''', and '''<tt>slider</tt>''' widgets to the layout using [http://doc.qt.nokia.com/latest/qboxlayout.html#addWidget Qt::BoxLayout::addWidget()]. | '''<tt>MyWidget</tt>''' now uses a [http://doc.qt.nokia.com/latest/qvboxlayout.html Qt::VBoxLayout] to manage the geometry of its child widgets. For that reason, we don't need to specify the screen coordinates for each widget like we did in Chapter 4. In addition, using a layout ensures that the child widgets are resized when the window is resized. Then we add the '''<tt>quit</tt>''', '''<tt>lcd</tt>''', and '''<tt>slider</tt>''' widgets to the layout using [http://doc.qt.nokia.com/latest/qboxlayout.html#addWidget Qt::BoxLayout::addWidget()]. | ||
</translate> | |||
<translate> | |||
<!--T:25--> | |||
The [http://doc.qt.nokia.com/latest/qwidget.html#setLayout Qt::Widget::setLayout()] function installs the layout on '''<tt>MyWidget</tt>'''. This makes the layout a child widget of '''<tt>MyWidget</tt>''' so we don't have to worry about deleting it; it will be deleted together with '''<tt>MyWidget</tt>'''. Also, the call to [http://doc.qt.nokia.com/latest/qwidget.html#setLayout Qt::Widget::setLayout()] automatically reparents the widgets in the layout so that they are children of '''<tt>MyWidget</tt>'''. Because of this, we didn't need to specify '''<tt>self</tt>''' as the parent for the '''<tt>quit</tt>''', '''<tt>lcd</tt>''', and '''<tt>slider</tt>''' widgets. | The [http://doc.qt.nokia.com/latest/qwidget.html#setLayout Qt::Widget::setLayout()] function installs the layout on '''<tt>MyWidget</tt>'''. This makes the layout a child widget of '''<tt>MyWidget</tt>''' so we don't have to worry about deleting it; it will be deleted together with '''<tt>MyWidget</tt>'''. Also, the call to [http://doc.qt.nokia.com/latest/qwidget.html#setLayout Qt::Widget::setLayout()] automatically reparents the widgets in the layout so that they are children of '''<tt>MyWidget</tt>'''. Because of this, we didn't need to specify '''<tt>self</tt>''' as the parent for the '''<tt>quit</tt>''', '''<tt>lcd</tt>''', and '''<tt>slider</tt>''' widgets. | ||
<!--T:26--> | |||
In Qt, widgets are either children of other widgets (e.g. '''<tt>self</tt>'''), or they have no parent. A widget can be ''added'' to a layout, in which case the layout becomes responsible for managing the geometry of that widget, but the layout can never act as a parent itself. Indeed, [http://doc.qt.nokia.com/latest/qwidget.html Qt::Widget]'s constructor takes a [http://doc.qt.nokia.com/latest/qwidget.html Qt::Widget] pointer for the parent, and [http://doc.qt.nokia.com/latest/qlayout.html Qt::Layout] doesn't inherit from [http://doc.qt.nokia.com/latest/qwidget.html Qt::Widget]. | In Qt, widgets are either children of other widgets (e.g. '''<tt>self</tt>'''), or they have no parent. A widget can be ''added'' to a layout, in which case the layout becomes responsible for managing the geometry of that widget, but the layout can never act as a parent itself. Indeed, [http://doc.qt.nokia.com/latest/qwidget.html Qt::Widget]'s constructor takes a [http://doc.qt.nokia.com/latest/qwidget.html Qt::Widget] pointer for the parent, and [http://doc.qt.nokia.com/latest/qlayout.html Qt::Layout] doesn't inherit from [http://doc.qt.nokia.com/latest/qwidget.html Qt::Widget]. | ||
</translate> | |||
=== Running the Application === | <translate> | ||
=== Running the Application === <!--T:27--> | |||
<!--T:28--> | |||
The LCD number reflects everything you do to the slider, and the widget handles resizing well. Notice that the LCD number widget changes in size when the window is resized (because it can), but the others stay about the same (because otherwise they would look strange). | The LCD number reflects everything you do to the slider, and the widget handles resizing well. Notice that the LCD number widget changes in size when the window is resized (because it can), but the others stay about the same (because otherwise they would look strange). | ||
=== Exercises === | === Exercises === <!--T:29--> | ||
<!--T:30--> | |||
Try changing the LCD number to add more digits or to change mode ([http://doc.qt.nokia.com/latest/qlcdnumber.html#mode-prop Qt::LCDNumber::setMode()]). You can even add four push buttons to set the number base. | Try changing the LCD number to add more digits or to change mode ([http://doc.qt.nokia.com/latest/qlcdnumber.html#mode-prop Qt::LCDNumber::setMode()]). You can even add four push buttons to set the number base. | ||
<!--T:31--> | |||
You can also change the slider's range. | You can also change the slider's range. | ||
<!--T:32--> | |||
Perhaps it would have been better to use [http://doc.qt.nokia.com/latest/qspinbox.html Qt::SpinBox] than a slider? | Perhaps it would have been better to use [http://doc.qt.nokia.com/latest/qspinbox.html Qt::SpinBox] than a slider? | ||
<!--T:33--> | |||
Try to make the application quit when the LCD number overflows. | Try to make the application quit when the LCD number overflows. | ||
<!--T:34--> | |||
[[Category:Ruby]] | |||
</translate> |
Latest revision as of 14:18, 18 July 2012
Tutorial Series | Qt4 Ruby Tutorial |
Previous | Tutorial 4 - Let There Be Widget |
What's Next | Tutorial 6 - Building Blocks Galore! |
Further Reading | n/a |
Building Blocks
Files:
Overview
This example shows how to create and connect together several widgets by using signals and slots, and how to handle resizes.
require 'Qt4'
class MyWidget < Qt::Widget
def initialize()
super()
quit = Qt::PushButton.new('Quit')
quit.setFont(Qt::Font.new('Times', 18, Qt::Font::Bold))
lcd = Qt::LCDNumber.new(2)
slider = Qt::Slider.new(Qt::Horizontal)
slider.setRange(0, 99)
slider.setValue(0)
connect(quit, SIGNAL('clicked()'), $qApp, SLOT('quit()'))
connect(slider, SIGNAL('valueChanged(int)'), lcd, SLOT('display(int)'))
layout = Qt::VBoxLayout.new()
layout.addWidget(quit)
layout.addWidget(lcd)
layout.addWidget(slider)
setLayout(layout)
end
end
app = Qt::Application.new(ARGV)
widget = MyWidget.new()
widget.show()
app.exec()
Line by Line Walkthrough
lcd = Qt::LCDNumber.new(2)
lcd is a Qt::LCDNumber, a widget that displays numbers in an LCD-like fashion. This instance is set up to display two digits.
slider = Qt::Slider.new(Qt::Horizontal)
slider.setRange(0, 99)
slider.setValue(0)
The user can use the Qt::Slider widget to adjust an integer value in a range. Here we create a horizontal one, set its minimum value to 0, its maximum value to 99, and its initial value to 0.
connect(slider, SIGNAL('valueChanged(int)'), lcd, SLOT('display(int)'))
Here we use the signals and slots mechanism to connect the slider's QAbstractSlider::valueChanged() signal to the LCD number's display() slot.
Whenever the slider's value changes it broadcasts the new value by emitting the QAbstractSlider::valueChanged() signal. Because that signal is connected to the LCD number's QLCDNumber::display() slot, the slot is called when the signal is broadcast. Neither of the objects knows about the other. This is essential in component programming.
layout = Qt::VBoxLayout.new()
layout.addWidget(quit)
layout.addWidget(lcd)
layout.addWidget(slider)
setLayout(layout)
MyWidget now uses a Qt::VBoxLayout to manage the geometry of its child widgets. For that reason, we don't need to specify the screen coordinates for each widget like we did in Chapter 4. In addition, using a layout ensures that the child widgets are resized when the window is resized. Then we add the quit, lcd, and slider widgets to the layout using Qt::BoxLayout::addWidget().
The Qt::Widget::setLayout() function installs the layout on MyWidget. This makes the layout a child widget of MyWidget so we don't have to worry about deleting it; it will be deleted together with MyWidget. Also, the call to Qt::Widget::setLayout() automatically reparents the widgets in the layout so that they are children of MyWidget. Because of this, we didn't need to specify self as the parent for the quit, lcd, and slider widgets.
In Qt, widgets are either children of other widgets (e.g. self), or they have no parent. A widget can be added to a layout, in which case the layout becomes responsible for managing the geometry of that widget, but the layout can never act as a parent itself. Indeed, Qt::Widget's constructor takes a Qt::Widget pointer for the parent, and Qt::Layout doesn't inherit from Qt::Widget.
Running the Application
The LCD number reflects everything you do to the slider, and the widget handles resizing well. Notice that the LCD number widget changes in size when the window is resized (because it can), but the others stay about the same (because otherwise they would look strange).
Exercises
Try changing the LCD number to add more digits or to change mode (Qt::LCDNumber::setMode()). You can even add four push buttons to set the number base.
You can also change the slider's range.
Perhaps it would have been better to use Qt::SpinBox than a slider?
Try to make the application quit when the LCD number overflows.