Qt-Ruby implementation of the "Address Book Example"

Hello,

I’m trying to implement the “Address Book Example” with Qt-Ruby.
http://doc.qt.nokia.com/4.7-snapshot/itemviews-addressbook.html

The problem that I face is that in the AddressWidget class, there are
two “addEntry” methods (one without parameter and the other with two
parameters) and they are both slots.

In Ruby, I think we can’t have two addEntry methods in the same class.
So, what is the solution? Only one addEntry method with a hash as only
parameter?

Thank you.

I’m not completely sure, but this should work:

  • define a method called add_entry which takes two optional arguments
    having
    nil as default value. Inside the method, you check whether one of the
    arguments is nil or not and choose the correct behaviour accordingly:

def add_entry name = nil, address = nil
if name and address
#behave as the addEntry(QString, QString) function
else
#behave as the addEntry() function
end
end

  • define two slots, one with no arguments and one with two arguments:

slots ‘add_entry()’, ‘add_entry(QString,QString)’

Note that this won’t work with signals: there can be only one signal
with a
given name, regardless of its signature.

I hope this helps

Stefano

Thank you for the reply!

Stefano C. wrote in post #962907:

I’m not completely sure, but this should work:

  • define a method called add_entry which takes two optional arguments
    having
    nil as default value. Inside the method, you check whether one of the
    arguments is nil or not and choose the correct behaviour accordingly:

def add_entry name = nil, address = nil
if name and address
#behave as the addEntry(QString, QString) function
else
#behave as the addEntry() function
end
end

Indeed, it works! The simplest solution is often the better! Thank you!

  • define two slots, one with no arguments and one with two arguments:

slots ‘add_entry()’, ‘add_entry(QString,QString)’

By the way, I have some questions again.

  • In this example, they use the QPair class. It seems that this class
    isn’t implemented in Qt-Ruby (as for the array and hash classes). So I
    use an array of size two instead and it seems to work fine. Is it the
    way to do it or do I have to use an other Ruby class to use QPair?
  • If I want to create a slot that have a Ruby hash as parameter, which
    QT class must I use in the slot declaration (QHash, QMap, …)?

Note that this won’t work with signals: there can be only one signal
with a
given name, regardless of its signature.

I didn’t knew that, thank you. Is it specific to Qt-Ruby or it is the
same in C++?

I hope this helps

Stefano

Yes it helps, thanks again!

On Sunday 21 November 2010 21:20:37 Arturo Bonechi wrote:

Thank you for the reply!

Stefano C. wrote in post #962907:

I’m not completely sure, but this should work:

  • define a method called add_entry which takes two optional arguments
    having
    nil as default value. Inside the method, you check whether one of the
    arguments is nil or not and choose the correct behaviour accordingly:

def add_entry name = nil, address = nil

if name and address

#behave as the addEntry(QString, QString) function

else

#behave as the addEntry() function

end

end

Indeed, it works! The simplest solution is often the better! Thank you!

  • define two slots, one with no arguments and one with two arguments:

slots ‘add_entry()’, ‘add_entry(QString,QString)’

By the way, I have some questions again.

  • In this example, they use the QPair class. It seems that this class
    isn’t implemented in Qt-Ruby (as for the array and hash classes). So I
    use an array of size two instead and it seems to work fine. Is it the
    way to do it or do I have to use an other Ruby class to use QPair?
    Yes, using an array here is correct. Everytime you see a collection
    looking
    like a list in C++ (for example, whenever they use QStringList), you
    need to
    replace it with an array in qtruby
  • If I want to create a slot that have a Ruby hash as parameter, which
    QT class must I use in the slot declaration (QHash, QMap, …)?

I don’t think you can do that. It seems that neither QHash nor QMap are
implemented in qtruby, and passing a native ruby hash doesn’t seem to
work. In my opinion, being restricted to using C++ types is one of the
most serious weaknesses of qtruby. In your case, I think the best option
would be to declare both signal with a string argument, then convert the
hash to a string (using Marshal or YAML) before emitting the signal and
converting it back in the slot.

Note that this won’t work with signals: there can be only one signal
with a
given name, regardless of its signature.

I didn’t knew that, thank you. Is it specific to Qt-Ruby or it is the
same in C++?

No, it’s another limitation of qtruby. It’s caused by the fact that
calling
signals creates a method taking a number of parameters according to the
signature you specified. Calling it again with the same name attempts to
create another method with the same name and (maybe) a different number
of
arguments. Since ruby doesn’t allow to have different methods with the
same
name, however, this effectively overwrites the first method.

Stefano

Stefano C. wrote in post #962925:

Yes, using an array here is correct. Everytime you see a collection
looking
like a list in C++ (for example, whenever they use QStringList), you
need to
replace it with an array in qtruby

Ok, thank you.

I don’t think you can do that. It seems that neither QHash nor QMap are
implemented in qtruby, and passing a native ruby hash doesn’t seem to
work. In my opinion, being restricted to using C++ types is one of the
most serious weaknesses of qtruby. In your case, I think the best option
would be to declare both signal with a string argument, then convert the
hash to a string (using Marshal or YAML) before emitting the signal and
converting it back in the slot.

So, I suppose that I need to do this conversion with arrays too… If
that is the price to pay it’s Ok for me.

No, it’s another limitation of qtruby. It’s caused by the fact that
calling
signals creates a method taking a number of parameters according to the
signature you specified. Calling it again with the same name attempts to
create another method with the same name and (maybe) a different number
of
arguments. Since ruby doesn’t allow to have different methods with the
same
name, however, this effectively overwrites the first method.

Ok, thanks for the explanation.

One last question :
In the Qt-Ruby declaration of signals and slots, the C++ keywords
“const” and “&” are sometimes added, but they aren’t added in the code
when a slot is “connected” (only the C++ type is mentioned).

For example :

slots ‘a_slot(const QString&)’

connect an_object, SIGNAL(‘a_signal(QString)’), self,
SLOT(‘a_slot(QString)’)

Must I add those keywords to the declaration or are they optional? When
do I know that I have to add them?

Thank you.

Stefano C. wrote in post #962967:

Yes, you need to do that also for arrays, except when they stand for a
QStringList (and maybe some other specialized class).

One last question :
In the Qt-Ruby declaration of signals and slots, the C++ keywords
“const” and “&” are sometimes added, but they aren’t added in the code
when a slot is “connected” (only the C++ type is mentioned).

For example :

slots ‘a_slot(const QString&)’

connect an_object, SIGNAL(‘a_signal(QString)’), self,
SLOT(‘a_slot(QString)’)

Must I add those keywords to the declaration or are they optional? When
do I know that I have to add them?

No, you don’t need them. The only modifier you need is the * for
pointers. For example,

slots ‘my_slot(QObject*)’

would be correct, while

slots ‘my_slot(QObject)’

would give you an error

Stefano

Ok, thanks for all this details!

Back to code, now!

Thank you.

On Monday 22 November 2010 00:05:32 Arturo Bonechi wrote:

Stefano C. wrote in post #962925:

I don’t think you can do that. It seems that neither QHash nor QMap are
implemented in qtruby, and passing a native ruby hash doesn’t seem to
work. In my opinion, being restricted to using C++ types is one of the
most serious weaknesses of qtruby. In your case, I think the best option
would be to declare both signal with a string argument, then convert the
hash to a string (using Marshal or YAML) before emitting the signal and
converting it back in the slot.

So, I suppose that I need to do this conversion with arrays too… If
that is the price to pay it’s Ok for me.

Yes, you need to do that also for arrays, except when they stand for a
QStringList (and maybe some other specialized class).

One last question :
In the Qt-Ruby declaration of signals and slots, the C++ keywords
“const” and “&” are sometimes added, but they aren’t added in the code
when a slot is “connected” (only the C++ type is mentioned).

For example :

slots ‘a_slot(const QString&)’

connect an_object, SIGNAL(‘a_signal(QString)’), self,
SLOT(‘a_slot(QString)’)

Must I add those keywords to the declaration or are they optional? When
do I know that I have to add them?

No, you don’t need them. The only modifier you need is the * for
pointers. For example,

slots ‘my_slot(QObject*)’

would be correct, while

slots ‘my_slot(QObject)’

would give you an error

Stefano