Qt signals driving me crazy

Below is source of basic window with TreeWidget on left and TabWidget on
the right. I stopped here because there is no way I can get
itemActivated() signal to call my nitem_clicked method. I have tried
practically everything I could find on net (there is very little Qt Ruby
examples beyond basics). Current source shows the most complicated
option, that I could have found ;-(

ruby 1.9.3
qtbindings (4.6.3.4)
kubuntu 10.4

by
TheR

···

-------------------------------------------------

require 'Qt'

class TreeView < Qt::TreeWidget

slots 'nitem_clicked(TreeWidgetItem*, int)'

##############################################
def initialize
  super
  init_ui
end

##############################################
def init_ui
  self.header_hidden = true

  item = Qt::TreeWidgetItem.new
  item.setText(0,'Mongo')
  addTopLevelItem(item)

  item = Qt::TreeWidgetItem.new #Qt::TreeViewItem.new()
  item.setText(0,'++ add new Mongo database')
  addTopLevelItem(item)

  connect(self, SIGNAL('itemActivated( TreeWidgetItem*, int )'), self,
SLOT('nitem_clicked(TreeWidgetItem*, int)'))

end

#############################################
def nitem_clicked(item, column)
  p item.inspect
end

end

##########################################
# Main app
##########################################
class QtApp < Qt::MainWindow
def initialize
  super
  init_ui
  resize 800, 600
  move 300, 300
  show
end

#############################################
def init_ui
  splitter = Qt::Splitter.new
  mongo_tree = TreeView.new
  splitter.addWidget mongo_tree

  mongo_tabs = Qt::TabWidget.new self
  tab = Qt::Widget.new
  mongo_tabs.addTab tab, 'Tab1'

  splitter.addWidget mongo_tabs
  setCentralWidget splitter

  quit = Qt::Action.new "&Quit", self
  file = menuBar.addMenu "&File"
  file.addAction quit

  self.connect(quit, SIGNAL("triggered()"), Qt::Application.instance,
SLOT("quit()"))
end

end

app = Qt::Application.new ARGV
QtApp.new
app.exec

--
Posted via http://www.ruby-forum.com/.

The correct signature for the signal is

'itemActivated( QTreeWidgetItem*, int )'

while you used

'itemActivated(TreeWidgetItem*, int )'

without the leading Q. You have the same problem in a couple of other places.
Generally speaking, when you have problems with a signal-slot connection, one
of the first things to do is to look at the output on standard error and see
if you see a warning saying 'not such a signal' or 'not such a slot' (this
warning is shown even if you're running ruby with warnings turned off, since
it is generated from the Qt library on the C++ side. Unfortunately, it doesn't
tell you where the wrong signal or slot name is).

I hope this helps

Stefano

···

On Friday 31 August 2012 Damjan Rems wrote

Below is source of basic window with TreeWidget on left and TabWidget on
the right. I stopped here because there is no way I can get
itemActivated() signal to call my nitem_clicked method. I have tried
practically everything I could find on net (there is very little Qt Ruby
examples beyond basics). Current source shows the most complicated
option, that I could have found ;-(

ruby 1.9.3
qtbindings (4.6.3.4)
kubuntu 10.4

by
TheR

Yeah. I was able to overcome the problem.

But now I have another signal, that doesn't work. It's the right mouse
click (context menu) on the same TreeWidget.

slots 'right_click(QPoint)'

connect(self, SIGNAL('customContextMenuRequested(const QPoint)'), self,
SLOT('right_click(const QPoint)') )

def right_click(point)
  p 'right_click', point
end

by
TheR

···

--
Posted via http://www.ruby-forum.com/.

And one more thing.

I would like to call my own slot function when main window is closed (to
save some settings when program is closed). How can I accomplish this?

by
TheR

···

--
Posted via http://www.ruby-forum.com/.

Stefano Crocco wrote in post #1074007:

by
TheR

The correct signature for the signal is

'itemActivated( QTreeWidgetItem*, int )'

while you used

'itemActivated(TreeWidgetItem*, int )'

without the leading Q. You have the same problem in a couple of other
places.
Generally speaking, when you have problems with a signal-slot
connection, one
of the first things to do is to look at the output on standard error and
see
if you see a warning saying 'not such a signal' or 'not such a slot'
(this
warning is shown even if you're running ruby with warnings turned off,
since
it is generated from the Qt library on the C++ side. Unfortunately, it
doesn't
tell you where the wrong signal or slot name is).

I hope this helps

Stefano

Thanks for your answer, I have already tried that too.

I oversleep problem a little, looked into source code and found
metaObject().signalNames method. The catch is that if I create
TreeWidget like:

t = Qt::TreeWidget.new
p t.metaObject().signalNames

I get nice output of all available signals, but if I write

p self.metaObject().signalNames

inside my defined TreeView class i get . Where is the catch?

by
TheR

···

On Friday 31 August 2012 Damjan Rems wrote

--
Posted via http://www.ruby-forum.com/\.

You can have a look at the documentation for QApplication::lastWindowClosed
and QCoreApplication::AboutToQuit.

Stefano

···

On Monday 03 September 2012 Damjan Rems wrote

And one more thing.

I would like to call my own slot function when main window is closed (to
save some settings when program is closed). How can I accomplish this?

by
TheR

--
Posted via http://www.ruby-forum.com/\.

Stefano Crocco wrote in post #1074007:
>
>> by
>> TheR
>
> The correct signature for the signal is
>
> 'itemActivated( QTreeWidgetItem*, int )'
>
> while you used
>
> 'itemActivated(TreeWidgetItem*, int )'
>
> without the leading Q. You have the same problem in a couple of other
> places.
> Generally speaking, when you have problems with a signal-slot
> connection, one
> of the first things to do is to look at the output on standard error and
> see
> if you see a warning saying 'not such a signal' or 'not such a slot'
> (this
> warning is shown even if you're running ruby with warnings turned off,
> since
> it is generated from the Qt library on the C++ side. Unfortunately, it
> doesn't
> tell you where the wrong signal or slot name is).
>
> I hope this helps
>
> Stefano

Thanks for your answer, I have already tried that too.

Do you mean that after replacing TreeWidgetItem with QTreeWidgetItem your
nitem_clicked slot still doesn't get called? If so, that's weird, since I
tried it and it works for me.

I oversleep problem a little, looked into source code and found
metaObject().signalNames method. The catch is that if I create
TreeWidget like:

t = Qt::TreeWidget.new
p t.metaObject().signalNames

I get nice output of all available signals, but if I write

p self.metaObject().signalNames

inside my defined TreeView class i get . Where is the catch?

by
TheR

It may be a bug in qtruby, but I'm not sure. You can ask on the QtRuby mailing
list (subscribing at https://mail.kde.org/mailman/listinfo/kde-bindings\). If
you don't, I'll do that one of the next days, as soon as I have a bit of free
time. However, I've noticed that if I define a new signal in the custom class,
metaObject#signalNames returns it, but it still doesn't contain signals from
the base class.

Stefano

···

On Friday 31 August 2012 Damjan Rems wrote

> On Friday 31 August 2012 Damjan Rems wrote

Damjan Rems писал 31.08.2012 10:58:

I oversleep problem a little, looked into source code and found
metaObject().signalNames method. The catch is that if I create
TreeWidget like:

t = Qt::TreeWidget.new
p t.metaObject().signalNames

I get nice output of all available signals, but if I write

p self.metaObject().signalNames

inside my defined TreeView class i get . Where is the catch?

As far as I understand, #metaObject only describes the exact class it
was called on, not a full ancestor tree. You might need to walk every
superclass to get complete information.

···

--
   WBR, Peter Zotov.

Stefano was right. It works now. I must have lost my nerves somewhere in
beetween ;-( The problem is that all three declarations must be the
same:

slots 'nitem_clicked(QTreeWidgetItem*, int)'

connect(self, SIGNAL('itemActivated( QTreeWidgetItem*, int )'),
self, SLOT('nitem_clicked(QTreeWidgetItem*, int)'))

Thanks guys.

···

----------------------

Now I have another problem. You can add text and icons to
Qt::TreeWidgetItem.

  item = Qt::TreeWidgetItem.new
  item.setText(0,'Test')
  item.setIcon(0, Qt::Icon.new('pics/test.png') )

But I would like to add an object. There is a method
QTreeWidgetItem::setData ( int column, int role, const QVariant & value
)

  If I use item.setData(0, Qt::UserRole, some_object) I get
     method_missing': undefined method `setData ...

which usually means that one of data type is not valid. Is there another
way to add object pointer to QTreeWidgetItem.

by
TheR

--
Posted via http://www.ruby-forum.com/.

setData requires s Qt::Variant as last argument, not a ruby object. In theory,
with sufficiently recent version of QtRuby, you should be able to create a
Qt::Variant from any ruby object using

Qt::Variant.from_value my_obj

When I tried it, however, I found out that it sometimes caused crashes. There
should also be another way to do so, which I haven't tried. Look at the first
example at
http://techbase.kde.org/Development/Languages/Ruby#Emitting_Ruby_Classes

If these methods don't work for you, your only option is to somehow create a
string or number or something else which you can put in a Qt::Variant and
which allows you to identify the object (the object_id of the object itself
could be a good candidate).

I hope this helps

Stefano

···

On Saturday 01 September 2012 Damjan Rems wrote

Stefano was right. It works now. I must have lost my nerves somewhere in
beetween ;-( The problem is that all three declarations must be the
same:

slots 'nitem_clicked(QTreeWidgetItem*, int)'

connect(self, SIGNAL('itemActivated( QTreeWidgetItem*, int )'),
self, SLOT('nitem_clicked(QTreeWidgetItem*, int)'))

Thanks guys.
----------------------

Now I have another problem. You can add text and icons to
Qt::TreeWidgetItem.

  item = Qt::TreeWidgetItem.new
  item.setText(0,'Test')
  item.setIcon(0, Qt::Icon.new('pics/test.png') )

But I would like to add an object. There is a method
QTreeWidgetItem::setData ( int column, int role, const QVariant & value
)

  If I use item.setData(0, Qt::UserRole, some_object) I get
     method_missing': undefined method `setData ...

which usually means that one of data type is not valid. Is there another
way to add object pointer to QTreeWidgetItem.

by
TheR

--
Posted via http://www.ruby-forum.com/\.