# (mandriva,eclipse,Qt) elementary problem : signals and slots

**URL:** <https://www.ruby-forum.com/t/mandriva-eclipse-qt-elementary-problem-signals-and-slots/167725>\
**Category:** Ruby\
**Created:** [May 11, 2009, 11:26pm UTC](https://www.ruby-forum.com/t/mandriva-eclipse-qt-elementary-problem-signals-and-slots/167725 "2009-05-11T23:26:00Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jolivierld](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@jolivierld](https://www.ruby-forum.com/u/jolivierld)\
**Post date:** [May 11, 2009, 11:26pm UTC](https://www.ruby-forum.com/t/mandriva-eclipse-qt-elementary-problem-signals-and-slots/167725/1 "2009-05-11T23:26:00Z")

</div>

hi,

I would like to make a little program using Qt : it’s a displayer /  
converter between farenheit and celsius degrees.  
I also want to use QtDesigner.

I made a little widget with QtDesigner, and this widget contains two  
dials(dial and dial\_2) and two spinboxes(kind of textboxes) (spinbox and  
spinbox\_2).  
There are some connections : see below for the ruby file I obtained with  
the tool rbuic4 (which converts the “.ui” file into “.rb”).  
my problem is this : I want that some changes made in dial\_2 modify dial  
(and then spinbox), eg :  
0 celsius degrees =\> 32 farenheit degrees.

here is the file made by rbuic4 and after this my try to modify the slot  
setValue (but it doesn’t run: the value of dial is always the same as  
the one of dial\_2.

temp.rb

* * *

=begin  
\*\* Form generated from reading ui file ‘temp.ui’  
\*\*  
\*\* Created: lun. mai 11 21:43:04 2009  
\*\* by: Qt User Interface Compiler version 4.5.0  
\*\*  
\*\* WARNING! All changes made in this file will be lost when recompiling  
ui file!  
=end

class Ui\_Form  
attr\_accessor :dial  
attr\_reader :dial\_2  
attr\_reader :spinBox  
attr\_reader :spinBox\_2

```
def setupUi(form)
if form.objectName.nil?
    form.objectName = "form"
end
form.resize(400, 300)
@dial = Qt::Dial.new(form)
@dial.objectName = "dial"
@dial.geometry = Qt::Rect.new(90, 40, 91, 101)
@dial_2 = Qt::Dial.new(form)
@dial_2.objectName = "dial_2"
@dial_2.geometry = Qt::Rect.new(230, 30, 91, 121)
@spinBox = Qt::SpinBox.new(form)
@spinBox.objectName = "spinBox"
@spinBox.geometry = Qt::Rect.new(100, 200, 58, 28)
@spinBox_2 = Qt::SpinBox.new(form)
@spinBox_2.objectName = "spinBox_2"
@spinBox_2.geometry = Qt::Rect.new(240, 200, 58, 28)

retranslateUi(form)
Qt::Object.connect(@dial_2, SIGNAL('valueChanged(int)'), @spinBox_2,

```

SLOT(‘setValue(int)’))  
Qt::Object.connect(@dial, SIGNAL(‘valueChanged(int)’), @spinBox,  
SLOT(‘setValue(int)’))  
Qt::Object.connect(@dial\_2, SIGNAL(‘valueChanged(int)’), @dial,  
SLOT(‘setValue(int)’))

```
Qt::MetaObject.connectSlotsByName(form)
end # setupUi

def setup_ui(form)
    setupUi(form)
end

def retranslateUi(form)
form.windowTitle = Qt::Application.translate("Form", "Form", nil,

```

Qt::Application::UnicodeUTF8)  
end # retranslateUi

```
def retranslate_ui(form)
    retranslateUi(form)
end

```

end

module Ui  
class Form \< Ui\_Form  
end  
end # module Ui

* * *

temp\_dsc\_form.rb

* * *

require ‘temp.rb’  
require ‘Qt4’

une\_appli=Qt::Application.new(ARGV)  
un\_wdg=Qt::Widget.new  
Un\_form=Ui\_Form.new  
Un\_form.setupUi(un\_wdg)

def (Un\_form.dial).setValue(v)

```
#super((1.8*v+32).to_i)
super(0)

```

end

un\_wdg.show  
une\_appli.exec

* * *

can you help me?

thx,

lolveley.

* * *

Yahoo! Mail réinvente le mail ! Découvrez le nouveau Yahoo! Mail et son  
interface révolutionnaire.

> **[Yahoo](https://mail.yahoo.com/)**
>
> It's

---

<div class="post-metadata">

**Author:** ![jolivierld](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@jolivierld](https://www.ruby-forum.com/u/jolivierld)\
**Post date:** [May 12, 2009, 8:18am UTC](https://www.ruby-forum.com/t/mandriva-eclipse-qt-elementary-problem-signals-and-slots/167725/2 "2009-05-12T08:18:41Z")

</div>

On Monday 11 May 2009, lolveley wrote:

> |the tool rbuic4 (which converts the “.ui” file into “.rb”).  
> |my problem is this : I want that some changes made in dial\_2 modify dial  
> |(and then spinbox), eg :  
> | 0 celsius degrees =\> 32 farenheit degrees.  
> |  
> |here is the file made by rbuic4 and after this my try to modify the slot  
> |setValue (but it doesn’t run: the value of dial is always the same as  
> |the one of dial\_2.

I don’t know why it doesn’t work, as I never used the designer to make  
signal/slot connections. I’d say it should work, but there might be some  
limitations which I’m not aware of. My suggestion is to use a custom  
widget  
class instead of a generic Qt::Widget and to implement the slot which  
converts  
the values there. Here’s how the tmp\_dsc\_form.rb could look like:

require ‘Qt4’  
require ‘temp.rb’

class MyWidget \< Qt::Widget

slots ‘change\_values(int)’

def initialize  
super  
@ui = Ui\_Form.new  
@ui.setupUi self  
connect @ui.dial\_2, SIGNAL(‘valueChanged(int)’), self,  
SLOT(‘change\_values(int)’)  
end

def change\_values val  
new\_value = (1.8\*val+32).to\_i  
@ui.spinBox.value = new\_value  
@ui.dial.value = new\_value  
end

end

une\_appli=Qt::Application.new(ARGV)  
un\_wdg = MyWidget.new  
un\_wdg.show  
une\_appli.exec

Of course, if you use this you can remove the connections made from the  
designer.

I hope this helps

Stefano

---

<div class="post-metadata">

**Author:** ![jolivierld](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@jolivierld](https://www.ruby-forum.com/u/jolivierld)\
**Post date:** [May 12, 2009, 2:06pm UTC](https://www.ruby-forum.com/t/mandriva-eclipse-qt-elementary-problem-signals-and-slots/167725/3 "2009-05-12T14:06:26Z")

</div>

On May 12, 7:17 am, Stefano C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > |I made a little widget with QtDesigner, and this widget contains two  
> > |the one of dial\_2.  
> > class MyWidget \< Qt::Widget
> 
> un\_wdg.show  
> une\_appli.exec
> 
> Of course, if you use this you can remove the connections made from the  
> designer.  
> I’m not sure if this solves the problem of making the changes bi-  
> directional because if you use the ‘valueChanged(int)’ signal, as you  
> will end up with a loop because each dial will try to change the  
> other.

I think the original rbuic4 generated code was nearly correct, but it  
should use ‘sliderMoved(int)’ signals in one dial connected to  
‘setValue(int)’ in the other dial because that would loop. And it  
needs an extra connection so that @dial\_2 is changed when @dial is  
changed.

```
Qt::Object.connect(@dial, SIGNAL('sliderMoved(int)'), @dial_2, SLOT

```

(‘setValue(int)’))  
Qt::Object.connect(@dial\_2, SIGNAL(‘sliderMoved(int)’), @dial, SLOT  
(‘setValue(int)’))

But that wouldn’t convert the values. So instead it needs an  
intermediate Qt::Object (doesn’t need to be a Qt::Widget) to convert  
the values as Stefano suggests.

– Richard

---

<div class="post-metadata">

**Author:** ![jolivierld](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@jolivierld](https://www.ruby-forum.com/u/jolivierld)\
**Post date:** [May 12, 2009, 5:41pm UTC](https://www.ruby-forum.com/t/mandriva-eclipse-qt-elementary-problem-signals-and-slots/167725/4 "2009-05-12T17:41:35Z")

</div>

On May 12, 3:21 pm, lolveley [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> the value in degree, and this slot emit a signal (here  
> dial.setValue(int)) which send the converted value (in Farenheit).  
> You could emit a signal from the intermediate ‘converter’ Qt::Widget  
> or Qt::Object which is connected to the target dial’s ‘setValue()’  
> slot, or you can just call the slot directly with the converted value

- the effect is the same.

> is it this?

In QtRuby, a slot can either be a normal Ruby method, or it can be a  
block. Maybe it is easier to understand if you connect a block  
directly to each dial’s ‘sliderMoved(int)’ signal, like this:

Un\_form.dial.connect(SIGNAL(‘sliderMoved(int)’)) do |farenheit|  
celcius = ((farenheit - 32) / 1.8).to\_i  
puts “dial: #{farenheit} farenheit ==\> #{celcius} celcius”  
Un\_form.dial\_2.value = celcius  
Un\_form.spinBox\_2.value = celcius  
end

Un\_form.dial\_2.connect(SIGNAL(‘sliderMoved(int)’)) do |celcius|  
farenheit = ((1.8 \* celcius) + 32).to\_i  
puts “dial\_2: #{celcius} celcius ==\> #{farenheit} farenheit”  
Un\_form.dial.value = farenheit  
Un\_form.spinBox.value = farenheit  
end

The you don’t need an intermediate Qt::Widget or Qt::Object to do the  
conversion calculations.

Note that in QtRuby you can write ‘setFoo(v)’ methods like ‘foo = v’,  
and so

Un\_form.spinBox.setValue(farenheit)

can also be written as:

Un\_form.spinBox.value = farenheit

– Richard

---

<div class="post-metadata">

**Author:** ![jolivierld](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@jolivierld](https://www.ruby-forum.com/u/jolivierld)\
**Post date:** [May 12, 2009, 9:17pm UTC](https://www.ruby-forum.com/t/mandriva-eclipse-qt-elementary-problem-signals-and-slots/167725/5 "2009-05-12T21:17:19Z")

</div>

hi stefano,

I tried your example and it works fine, but I find this is not very  
simple, indeed this is a basic example : what would it be for a more  
complicated example?

lolveley.

Stefano C. a écrit :

> > |spinbox\_2).
> 
> def change\_values val  
> une\_appli.exec
> 
> Of course, if you use this you can remove the connections made from the  
> designer.
> 
> I hope this helps
> 
> Stefano

* * *

Yahoo! Mail réinvente le mail ! Découvrez le nouveau Yahoo! Mail et son  
interface révolutionnaire.

> **[Yahoo Mail](https://mail.yahoo.com/)**
>
> Take a trip into an upgraded, more organized inbox. Sign in and start exploring all the free, organizational tools for your email. Check out new themes, send GIFs, find every photo you've ever sent or received, and search your account faster than...

---

<div class="post-metadata">

**Author:** ![jolivierld](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@jolivierld](https://www.ruby-forum.com/u/jolivierld)\
**Post date:** [May 13, 2009, 11:47am UTC](https://www.ruby-forum.com/t/mandriva-eclipse-qt-elementary-problem-signals-and-slots/167725/6 "2009-05-13T11:47:56Z")

</div>

On Tuesday 12 May 2009, lolveley wrote:

> |\> @ui = Ui\_Form.new  
> |\>  
> |\> end  
> |\>  
> |\> une\_appli=Qt::Application.new(ARGV)  
> |\> un\_wdg = MyWidget.new  
> |\> un\_wdg.show  
> |\> une\_appli.exec

> |hi stefano,  
> |  
> |I tried your example and it works fine, but I find this is not very  
> |simple, indeed this is a basic example : what would it be for a more  
> |complicated example?  
> |  
> |lolveley.

The concept is quite simple: you want to do something when the value of  
the  
second dial changes. In particular, you want to:

1. make the second spin box show the value chosen with the second dial
2. set the value of the first dial to the equivalent in Farenheit  
degrees of  
the value in the second dial
3. make the first spin box show the value chosen with the first dial

As you have already discovered, the first goal can be achieved directly  
from  
the UI designer: the dial has a signal which informs of the fact that  
the  
value has changed and the spin box has a slot which allows to change the  
value  
it displays: connect the signal and the slot and you’re done.

The second and third goal require a bit more work, as there’s no  
suitable slot  
in the first dial which make the conversion for you. In theory, this  
would  
mean that you have to create a Qt::Object-derived class, define a method  
which  
does the conversion and sets the value of the first dial, and declare it  
as a  
slot using the slots class method. In my code, I did this in the dial’s  
parent  
widget, because I think it’s the natural place to put code which  
connects  
together the behaviour of two child widgets, but you don’t have to do  
that.  
However, as Richard suggested, in Ruby you have another choice to do  
that:  
instead of connecting signals to slots, you can connect them to a block.  
This  
way, you could keep all of your original code, replacing the method  
definition  
with a connection to a block. It could look like this:

require ‘temp.rb’  
require ‘Qt4’

une\_appli=Qt::Application.new(ARGV)  
un\_wdg=Qt::Widget.new  
Un\_form=Ui\_Form.new  
Un\_form.setupUi(un\_wdg)  
Un\_form.dial\_2.connect(SIGNAL(‘valueChanged(int)’)) do |v|  
new\_val = (1.8\*val+32).to\_i  
Un\_form.dial.value = new\_val  
Un\_form.spinBox.value = new\_val  
end

un\_wdg.show  
une\_appli.exec

A block connected with a signal will be called whenever the signal is  
emitted,  
just like a slot, and the signal’s argument will be passed to the block  
(the  
only downside of using blocks is that you can’t disconnect them using  
Qt::Object#disconnect).

To avoid having to remember to change the value of the first spin box,  
you can  
also connect the first dial’s valueChanged signal to the first spin box  
setValue slot (you can do this from the designer) and remove the last  
line of  
the block above. When the block is called and the value of the first  
dial  
changes, it will emit the valueChanged signal with the new value as  
argument  
and that will trigger the setValue slot of the spin box.

If you want to learn more about Qt programming, I suggest you the  
excellent Qt  
tutorial you can find at  
[http://doc.trolltech.com/4.4/tutorials-tutorial.html](http://doc.trolltech.com/4.4/tutorials-tutorial.html) (it seems it has  
been  
removed from Qt 4.5 but you can find it in the documentation if you have  
a  
less recent version). It’s written for C++, but it should be quite easy  
to  
understant. You can also find a ruby version of the tutorial in the  
qtruby  
source tarball in the ruby/qtruby/examples/tutorial directory.

I hope this helps

Stefano

---

<div class="post-metadata">

**Author:** ![jolivierld](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@jolivierld](https://www.ruby-forum.com/u/jolivierld)\
**Post date:** [May 12, 2009, 4:22pm UTC](https://www.ruby-forum.com/t/mandriva-eclipse-qt-elementary-problem-signals-and-slots/167725/7 "2009-05-12T16:22:03Z")

</div>

hello,

thank you richard and stefano for your answers.  
I’m afraid I haven’t well understood the system of slots, if I want to  
rewrite a slot - say setValue(int) - of a dial what can I put in this  
method? I have to put a statement telling the slot to modify graphically  
the widget, but I don’t think it is possible.

I think \_ but I’m not sure \_ I have understood the solution of richard :  
it is to create a class with a slot (for example setValue) which receive  
the value in degree, and this slot emit a signal (here  
dial.setValue(int)) which send the converted value (in Farenheit).

is it this?

lolveley.

removed\_email\_address@domain.invalid a écrit :

> > > |converter between farenheit and celsius degrees.  
> > > |  
> > > require ‘Qt4’  
> > > connect @ui.dial\_2, SIGNAL(‘valueChanged(int)’), self,
> 
> will end up with a loop because each dial will try to change the  
> Qt::Object.connect(@dial\_2, SIGNAL(‘sliderMoved(int)’), @dial, SLOT

* * *

Yahoo! Mail réinvente le mail ! Découvrez le nouveau Yahoo! Mail et son  
interface révolutionnaire.

> **[Yahoo Mail](https://mail.yahoo.com/)**
>
> Take a trip into an upgraded, more organized inbox. Sign in and start exploring all the free, organizational tools for your email. Check out new themes, send GIFs, find every photo you've ever sent or received, and search your account faster than...
