# Using qui rather than rbuic for qtdesigner .ui files

**URL:** <https://www.ruby-forum.com/t/using-qui-rather-than-rbuic-for-qtdesigner-ui-files/157653>\
**Category:** Ruby\
**Created:** [January 14, 2009, 5:38am UTC](https://www.ruby-forum.com/t/using-qui-rather-than-rbuic-for-qtdesigner-ui-files/157653 "2009-01-14T05:38:26Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [January 14, 2009, 5:38am UTC](https://www.ruby-forum.com/t/using-qui-rather-than-rbuic-for-qtdesigner-ui-files/157653/1 "2009-01-14T05:38:26Z")

</div>

I’m trying to load .ui files at runtime using the qui extension and  
WidgetFactory rather than pre-translating the .ui XML file to ruby with  
rbuic. Here’s a simple program:

```
  require 'Qt'
  require 'qui'
  a = Qt::Application.new(ARGV)
  w = QUI::WidgetFactory.create "sampledialog.ui"
  w.show()
  a.connect(a, SIGNAL('lastWindowClosed()'), a, SLOT('quit()'))
  a.exec()

```

This works just fine in that it dynamically loads and presents the .ui  
file as a window. However, how do I connect signals and slots? I  
understand the process of method override when doing it the rbuic way,  
but this doesn’t seem to be working with WidgetFactory. The signals and  
slots (but not their handling) are defined in the .ui file. Could  
someone give this noob an example of how to implement a slot method? I  
tried looking at some C++ examples, but I’m just not making the  
connection to ruby. The .ui file is below. It just has two buttons,  
Test and Close.

Thanks,

David

SampleDialogUI  
  
  
SampleDialogUI  
  
  
  
0  
0  
155  
45  
  
  
  
Sample Dialog  
  
  
true  
  
  
  
unnamed  
  
  
  
closeButton  
  
  
Close  
  
  
Close this dialog  
  
  
  
  
testButton  
  
  
Test  
  
  
Test command execution  
  
  
  
  
  
  
testButton  
clicked()  
SampleDialogUI  
testButton\_clicked()  
  
  
closeButton  
clicked()  
SampleDialogUI  
closeButton\_clicked()  
  
  
  
testButton\_clicked()  
closeButton\_clicked()

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [January 14, 2009, 10:04am UTC](https://www.ruby-forum.com/t/using-qui-rather-than-rbuic-for-qtdesigner-ui-files/157653/2 "2009-01-14T10:04:31Z")

</div>

Alle mercoledÃ¬ 14 gennaio 2009, David Brunell ha scritto:

> ```
> a.exec()
> 
> ```
> 
> Thanks,
> 
> David

Not tested, because I’m using Qt 4 while, I think, you’re using Qt 3.  
The idea  
is to create a custom widget class and to add the widget returned by  
WidgetFactory.create as child widget. You shouldn’t define custom slots  
in the  
ui file, since there’s no way to implement them. Any custom slot you’d  
define  
in the ui file is instead defined in the custom widget. Here’s a simple  
example which should work:

require ‘Qt’  
require ‘qui’

class MainWidget \< Qt::Widget

slots ‘test()’

def initialize  
@widget = QUI::WidgetFactory.create “sampledialog.ui”  
self.layout = Qt::VBoxLayout.new  
self.layout.add\_widget @widget  
connect @widget.child(‘testButton’), SIGNAL(‘clicked()’), self,  
SLOT(‘test()’)  
end

def test  
puts “test button clicked”  
end

end

app = Qt::Application.new ARGV  
w = MainWidget.new  
w.show  
a.connect(a, SIGNAL(‘lastWindowClosed()’), a, SLOT(‘quit()’))  
a.exec

I hope this helps

Stefano

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [January 15, 2009, 4:04pm UTC](https://www.ruby-forum.com/t/using-qui-rather-than-rbuic-for-qtdesigner-ui-files/157653/3 "2009-01-15T16:04:47Z")

</div>

Stefano C. wrote:

> require ‘Qt’  
> require ‘qui’
> 
> class MainWidget \< Qt::Widget
> 
> slots ‘test()’
> 
> def initialize  
> @widget = QUI::WidgetFactory.create “sampledialog.ui”  
> self.layout = Qt::VBoxLayout.new  
> self.layout.add\_widget @widget  
> connect @widget.child(‘testButton’), SIGNAL(‘clicked()’), self,  
> SLOT(‘test()’)  
> end
> 
> def test  
> puts “test button clicked”  
> end
> 
> end
> 
> app = Qt::Application.new ARGV  
> w = MainWidget.new  
> w.show  
> a.connect(a, SIGNAL(‘lastWindowClosed()’), a, SLOT(‘quit()’))  
> a.exec

Many thanks for your kind reply. I get the following error when running  
your suggested code:

quitest2.rb:10:in `method_missing': undefined method`layout=’ for  
:MainWidget (NoMethodError)

I somewhat understand this error, but upon commenting out the two  
self.layout lines, I then get the following error:

quitest2.rb:12:in `method_missing': super: no superclass method`connect’(NoMethodError)

If I change “connect” to “Qt::Object.connect” (this is what the rbuic  
compiler would generate) the error persists. Any ideas?

Thanks,

David

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [January 18, 2009, 8:59pm UTC](https://www.ruby-forum.com/t/using-qui-rather-than-rbuic-for-qtdesigner-ui-files/157653/4 "2009-01-18T20:59:03Z")

</div>

Stefano C. wrote:

> Sorry, I forgot one line. The initialize method should be:
> 
> def initialize  
> super # this is the new part

Well, now I get no errors. However, the dialog which appears is a blank  
dialog, not the one which I designed with Qt designer. Any thoughts? I  
can always go back to the rbuic compiler if I have to. Here is my code  
at this point:

########################  
require ‘Qt’  
require ‘qui’

class MainWidget \< Qt::Widget

slots ‘test()’

def initialize  
super  
@widget = QUI::WidgetFactory.create “sampledialog.ui”  
set\_layout = Qt::VBoxLayout.new  
set\_layout.add\_widget @widget  
connect @widget.child(‘testButton’), SIGNAL(‘clicked()’), self,  
SLOT(‘test()’)  
end

def test  
puts “test button clicked”  
end

end

a = Qt::Application.new ARGV  
w = MainWidget.new  
w.show  
a.connect(a, SIGNAL(‘lastWindowClosed()’), a, SLOT(‘quit()’))  
a.exec  
################################

Many thanks,

David

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [January 19, 2009, 10:07pm UTC](https://www.ruby-forum.com/t/using-qui-rather-than-rbuic-for-qtdesigner-ui-files/157653/5 "2009-01-19T22:07:45Z")

</div>

Ok, I got it working. Here is my code:

##########################################  
require ‘Qt’  
require ‘qui’

class MainWidget \< Qt::Widget

slots ‘test()’, ‘close()’

def initialize(app)  
super()  
@app = app  
@widget = QUI::WidgetFactory.create “sampledialog.ui”  
connect @widget.child(‘testButton’), SIGNAL(‘clicked()’), self,  
SLOT(‘test()’)  
connect @widget.child(‘closeButton’), SIGNAL(‘clicked()’), self,  
SLOT(‘close()’)  
@widget.show  
end

def test  
puts “test button clicked”  
end

def close  
@app.exit(0)  
end

end

app = Qt::Application.new ARGV  
dialog = MainWidget.new(app)  
app.exec  
######################################

The .ui file is the same as in the original post. I’m not sure this is  
the most elegant way to make it work, so if you have any ideas on how to  
clean it up, I’m open to suggestions.

One other question…what about Qt4? I think I need rbuic4 if I am  
going to pre-compile the ui. Is there a qui4 for dynamic loading?

Kind regards,

David

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [January 15, 2009, 7:13pm UTC](https://www.ruby-forum.com/t/using-qui-rather-than-rbuic-for-qtdesigner-ui-files/157653/6 "2009-01-15T19:13:15Z")

</div>

Alle giovedÃ¬ 15 gennaio 2009, David Brunell ha scritto:

> > ```
> > self.layout = Qt::VBoxLayout.new
> > 
> > ```
> 
> :MainWidget (NoMethodError)
> 
> I somewhat understand this error, but upon commenting out the two  
> self.layout lines, I then get the following error:
> 
> quitest2.rb:12:in `method_missing': super: no superclass method`connect’(NoMethodError)

Sorry, I forgot one line. The initialize method should be:

def initialize  
super # this is the new part  
@widget = QUI::WidgetFactory.create “sampledialog.ui”  
self.layout = Qt::VBoxLayout.new  
self.layout.add\_widget @widget  
connect @widget.child(‘testButton’), SIGNAL(‘clicked()’), self,  
SLOT(‘test()’)  
end

This will solve the second problem and most likely also the first. If  
the firs  
remains, try replacing

self.layout =

set\_layout

Stefano

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [January 21, 2009, 11:05am UTC](https://www.ruby-forum.com/t/using-qui-rather-than-rbuic-for-qtdesigner-ui-files/157653/7 "2009-01-21T11:05:11Z")

</div>

Alle mercoledÃ¬ 21 gennaio 2009, Stefano C. ha scritto:

> ```
> file.close
> puts "testing"
> 
> ```
> 
> end
> 
> end
> 
> app = Qt::Application.new ARGV  
> dlg = Dlg.new  
> dlg.exec  
> app.exec
> 
> Stefano

My previous code contained an error: the clicked() signal of @close\_btn  
should  
be connected to the quit() slot of Qt::Application.instance, not to the  
close() signal (which it doesn’t exist).

Also, to work around the bug I spoke about, it’s enough to replace  
Qt::PushButton with Qt::Object in the two calls to findChild.

Stefano

---

<div class="post-metadata">

**Author:** ![david](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@david](https://www.ruby-forum.com/u/david)\
**Post date:** [January 21, 2009, 10:58am UTC](https://www.ruby-forum.com/t/using-qui-rather-than-rbuic-for-qtdesigner-ui-files/157653/8 "2009-01-21T10:58:06Z")

</div>

Alle lunedÃ¬ 19 gennaio 2009, David Brunell ha scritto:

> One other question…what about Qt4? Â I think I need rbuic4 if I am  
> going to pre-compile the ui. Â Is there a qui4 for dynamic loading?

The following should work using a recent svn revision from kdebindings.  
However, it doesn’t because findChild fails. I think it’s a bug and I’ll  
try  
to contact the developers to

require ‘Qt4’  
require ‘qtuitools’

class Dlg \< Qt::Dialog

slots ‘test()’

def initialize parent = nil  
super  
file = Qt::File.new File.expand\_path(’~/temp/test\_ui.ui’)  
file.open(Qt::File::ReadOnly)  
loader = Qt::UiLoader.new  
@widget = loader.load file, self  
file.close  
self.layout = Qt::VBoxLayout.new self  
layout.add\_widget @widget  
@close\_btn = @widget.findChild(Qt::PushButton, ‘close\_btn’)  
@test\_btn = @widget.findChild(Qt::PushButton, ‘test\_btn’)  
connect @close\_btn, SIGNAL(‘clicked()’), Qt::Application.instance,  
SLOT(‘close()’)  
connect @test\_btn, SIGNAL(‘clicked()’), self, SLOT(‘test()’)  
end

def test  
puts “testing”  
end

end

app = Qt::Application.new ARGV  
dlg = Dlg.new  
dlg.exec  
app.exec

Stefano
