Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QtRuby connect signals and slots with parameters/arguments

Tags:

ruby

qt

qt4

qtruby

I would like to know how I can connect to a signal that take parameters (using Ruby blocks).

I know how to connect to one which does not take parameters:

myCheckbox.connect(SIGNAL :clicked) { doStuff }

However, this does not work:

myCheckbox.connect(SIGNAL :toggle) { doStuff }

It doesn't work because the toggle slot take a parameter void QAbstractButton::toggled ( bool checked ). How can I make it work with parameters?

Thanks.

like image 571
Jean-Luc Avatar asked Dec 04 '12 00:12

Jean-Luc


People also ask

How do I connect Qt signals and slots?

There are several ways to connect signal and slots. The first is to use function pointers: connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed); There are several advantages to using QObject::connect() with function pointers.

In what order will the slots be executed if they are connected to one signal?

if several slots are connected to one signal, the slots will be executed one after the other, in the order they have been connected, when the signal is emitted.

Is it possible to use Qt with 3rd party signals/slots?

It is possible to use Qt with a 3rd party signal/slot mechanism. You can even use both mechanisms in the same project. To do that, write the following into your CMake project file: It tells Qt not to define the moc keywords signals, slots, and emit, because these names will be used by a 3rd party library, e.g. Boost.

How to connect signals and slots in QML?

Connecting signals inside QML files 1. Connect a signal to a signal 2. Using Variables in Signals 4. Conclusion Let's create our first class that will work with signals and slots in QML. This is one of the very first examples that I have already shown, but I will repeat this example so that the article is as complete as possible.

What are QObject signals and slots?

Signals and slots can take any number of arguments of any type. They are completely type safe. All classes that inherit from QObject or one of its subclasses (e.g., QWidget) can contain signals and slots. Signals are emitted by objects when they change their state in a way that may be interesting to other objects.

How can I Pass custom arguments to a slot in Qt?

Lambda expressions are a convenient way to pass custom arguments to a slot: It is possible to use Qt with a 3rd party signal/slot mechanism. You can even use both mechanisms in the same project. To do that, write the following into your CMake project file:


1 Answers

The short answer to your question is that you must declare your method signature for the slot to connect to, using the slots method:

class MainGUI < Qt::MainWindow
  # Declare all the custom slots that we will connect to
  # Can also use Symbol for slots with no params, e.g. :open and :save
  slots 'open()', 'save()',
        'tree_selected(const QModelIndex &,const QModelIndex &)'

  def initialize(parent=nil)
    super
    @ui = Ui_MainWin.new # Created by rbuic4 compiling a Qt Designer .ui file
    @ui.setupUi(self)    # Create the interface elements from Qt Designer
    connect_menus!
    populate_tree!
  end

  def connect_menus!
    # Fully explicit connection
    connect @ui.actionOpen, SIGNAL('triggered()'), self, SLOT('open()')

    # You can omit the third parameter if it is self
    connect @ui.actionSave, SIGNAL('triggered()'), SLOT('save()')

    # close() is provided by Qt::MainWindow, so we did not need to declare it
    connect @ui.actionQuit,   SIGNAL('triggered()'), SLOT('close()')       
  end

  # Add items to my QTreeView, notify me when the selection changes
  def populate_tree!
    tree = @ui.mytree
    tree.model = MyModel.new(self) # Inherits from Qt::AbstractItemModel
    connect(
      tree.selectionModel,
      SIGNAL('currentChanged(const QModelIndex &, const QModelIndex &)'),
      SLOT('tree_selected(const QModelIndex &,const QModelIndex &)')
    )
  end

  def tree_selected( current_index, previous_index )
    # …handle the selection change…
  end

  def open
    # …handle file open…
  end

  def save
    # …handle file save…
  end
end

Note that the signatures passed to SIGNAL and SLOT do not include any variable names.

Also, as you concluded in your comment, it is simpler (and more Ruby-esque) to do away with the "slot" concept altogether and just use a Ruby block to connect the signal to invoke whatever method you like (or put the logic inline). Using the following syntax, you do not need to use the slots method to pre-declare your method or handling code.

changed = SIGNAL('currentChanged(const QModelIndex &, const QModelIndex &)')

# Call my method directly
@ui.mytree.selectionMode.connect( changed, &method(:tree_selected) )

# Alternatively, just put the logic in the same spot as the connection
@ui.mytree.selectionMode.connect( changed ) do |current_index, previous_index|
  # …handle the change here…
end
like image 124
Phrogz Avatar answered Oct 09 '22 11:10

Phrogz