[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Qt problems

Damjan Rems

6/13/2009 12:02:00 AM

require 'Qt4'
class MainWindow < Qt::MainWindow
def initialize
super
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(tr '<big>Hello Qt in the Ruby way!</big>')

layout1 = Qt::VBoxLayout.new do
add_widget(label, 0, Qt::AlignCenter)
add_widget(button, 0, Qt::AlignRight)
end
central_widget = layout1

#create_menubar
@statusbar = Qt::StatusBar.new(self)
@statusbar.setObjectName('statusbar')
set_status_bar(@statusbar)
@statusbar.show_message tr("Some text");
end
end
if $0 == __FILE__
a = Qt::Application.new(ARGV)
w = MainWindow.new
w.show
a.exec
end

I am learning qt4 with ruby and have got to a problem that is driving me
crazy. Acording to what I was able to find on Internet

central_widget = layout1

should paint a label and a box in the window. But it doesn't. It doesn't
show anything.

Original c++ documentation points to setCentralWidget( layout1 ) method
but it doesn't exist in ruby Qt4.

It looks like that Qt with ruby is not used a lot. Can anybody confirm
should this work at all or is it a bug.


by
TheR
--
Posted via http://www.ruby-....

3 Answers

Stefano Crocco

6/13/2009 7:44:00 AM

0

On Saturday 13 June 2009, Damjan Rems wrote:
> |require 'Qt4'
> |class MainWindow < Qt::MainWindow
> | def initialize
> | super
> | 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(tr '<big>Hello Qt in the Ruby way!</big>')
> |
> | layout1 = Qt::VBoxLayout.new do
> | add_widget(label, 0, Qt::AlignCenter)
> | add_widget(button, 0, Qt::AlignRight)
> | end
> | central_widget = layout1
> |
> | #create_menubar
> | @statusbar = Qt::StatusBar.new(self)
> | @statusbar.setObjectName('statusbar')
> | set_status_bar(@statusbar)
> | @statusbar.show_message tr("Some text");
> | end
> |end
> |if $0 == __FILE__
> | a = Qt::Application.new(ARGV)
> | w = MainWindow.new
> | w.show
> | a.exec
> |end
> |
> |I am learning qt4 with ruby and have got to a problem that is driving me
> |crazy. Acording to what I was able to find on Internet
> |
> | central_widget = layout1
> |
> |should paint a label and a box in the window. But it doesn't. It doesn't
> |show anything.

I don't know where you found this, but it's clearly incorrect. The C++ method
setCentralWidget (which in ruby can be called with the three names
setCentralWidget, set_central_widget and central_widget=) takes a widget as
argument. layout1 is a Qt::Layout, not a Qt::Widget, so you can't pass it to
setCentralWidget.

> |
> |Original c++ documentation points to setCentralWidget( layout1 ) method
> |but it doesn't exist in ruby Qt4.

As I explained above, the setCentralWidget does exist, but it requires a
Qt::Widget as argument. Here you've come across one of the peculiarities of
QtRuby: most ruby libraries either don't check methods arguments types or
raise ArgumentError or TypeError if one argument is of the wrong type. QtRuby,
instead, checks the arguments, but raises NoMethodError if the argument is of
the wrong type. Since you're calling setCentralWidget with an argument of the
wrong type (Qt::Layout instead of Qt::Widget) you get a NoMethodError.

The reason why you don't get the error when calling central_widget= is that
here you're not actually calling the method, but creating a local variable
called central_widget. This isn't a qtruby issue, but a quirk of the ruby
syntax: whenever ruby sees something which can be a local variable followed by
an equal sign, it interprets it as a local variable assignement. This means
that to have ruby understand you're calling the central_widget= method of the
main window, you have to call it using the dot notation:

self.central_widget = widget

(this is an issue only when calling a method ending in = on self: if you're
calling it on another object, you naturally do it using the dot notation, so
there can be no ambiguity).

Here's a working version of your code:

require 'Qt4'
class MainWindow < Qt::MainWindow
def initialize
super
self.window_title = 'Hello QtRuby v1.0'
resize(200, 100)
cw = Qt::Widget.new self
self.central_widget = cw

button = Qt::PushButton.new('Quit', cw) do
connect(SIGNAL :clicked) { Qt::Application.instance.quit }
end

label = Qt::Label.new(Qt::Object.tr('<big>Hello Qt in the Ruby
way!</big>'), cw)

cw.layout = Qt::VBoxLayout.new cw do
add_widget(label, 0, Qt::AlignCenter)
add_widget(button, 0, Qt::AlignRight)
end

status_bar.show_message Qt::Object.tr('Some text')
end
end
if $0 == __FILE__
a = Qt::Application.new(ARGV)
w = MainWindow.new
w.show
a.exec
end


I made several changes:
* replaced calls to tr with calls to Qt::Object.tr. In C++, QObject::tr is a
static method, which means it becomes a class method in ruby. But class
methods can't be called directly from instances of the class, so you need to
explicitly add the receiver (Qt::Object)
* removed most of the code related to status bar initialization: calling
Qt::MainWindow#status_bar when no status bar has been created automatically
creats one, so there's no need to do it manually (of course, if you wanted
your status bar to be of a custom class, you'd need to create it manually)
* changed the code related to the central widget. Here, you'll need to
understand how Qt::MainWindow exactly works. It already has a layout (if you
tried to change its layout using self.layout=Qt::VBoxLayout.new you'd get a
warning telling you this). This layout makes one widget, called the central
widget, fill all the window (except for the space reserved for the menu bar,
the status bar and the toolbars). All the widgets you want to appear in the
main window should actually go in this central widget. You could create a
separate class for it or you can simply use a simple Qt::Widget, as I did.
After creating the central widget (I assigned it to the local variable cw only
to avoid typing central_widget every time), we tell the main window to use it
as central widget, using the central_widget= method (note that we have to call
it using self.central_widget=, for the reason I explained above). After that,
we create the button and the label (note that they're children of the central
widget now, not of the main window itself). Finally, we create the layout, set
it as layout for the central widget and add the button and the label to it.


> |It looks like that Qt with ruby is not used a lot.

I'm not so sure about this.

I hope this helps

Stefano

Damjan Rems

6/13/2009 7:04:00 PM

0


Thanks man. You are a saviour. I was following what could be found here
http://techbase.kde.org/Development/Lang.... And it seems a
little rusty.

Can you tell any good Ruby Qt tutorial on the web?


by
TheR
--
Posted via http://www.ruby-....

Stefano Crocco

6/14/2009 7:26:00 AM

0

On Saturday 13 June 2009, Damjan Rems wrote:
> |Thanks man. You are a saviour. I was following what could be found here
> |http://techbase.kde.org/Development/Lang.... And it seems a
> |little rusty.
> |
> |Can you tell any good Ruby Qt tutorial on the web?
> |
> |
> |by
> |TheR
Have you looked at the tutorial which comes with qtruby itself? It's located
in the ruby/qtruby/examples/tutorial directory of the source distribution and
corresponds to a very detailed tutorial which was shipped with qt until
version 4.5.

Stefano