简体   繁体   中英

Qt forward slot / connect slot to slot?

I came into situation where I have to call object's slot after receive signal (just forward the signal to the other's object slot). I know I can simply implement slot and call another slot from the body, but maybe I can do it in more simple way?

Here's sample code:

class SomeWidget : public QObject
{
    Q_OBJECT
signals:
    textChanged(QString);
    //...
};

//----------------------------------------------------------------------

class SomeController : public QObject
{
    Q_OBJECT
public slots:
    processText(QString);
    //...

public:
    SomeController()
    {
        connect(this, &SomeController::processText, &someUtil, &SomeUtil::processText);
        //^^ this won't work, linker can not find SomeController::processText
    }
private:
    SomeUtil someUtil; //doesn't matter, just does something
};

//----------------------------------------------------------------------

//code somewhere else
connect (someWidget, &SomeWidget::textChanged, someController, &SomeController::processText)

EDIT:

OK, maybe my question is not clear enough - concidering my example - I don't want to connect directly SomeWidget with SomeUtil as I want to hide fact that I even use SomeUtil . This class should be invisible for SomeController 's user. It's a matter of encapsulation. SomeController is kind of facade.

What is more I don't need to implement SomeController 's slot. It's only work is to call SomeUtil 's slot (forward the signal).

您可以将信号连接到两个插槽,然后按照连接的顺序将它们都调用。

  1. answering your question: you can make two connections one-by-one and slots will be called in the same sequence something like

     connect(someWidget, &SomeWidget::textChanged, someController, &SomeController::processText); connect(someWidget, &SomeWidget::textChanged, anotherController, &SomeController::processText); 

this is useful if you need to call multiple slots:

connect(someWidget, &SomeWidget::textChanged, someController, &SomeController::processText);
connect(someWidget, &SomeWidget::textChanged, someController, &SomeController::update);

but if you need to call private member function of the same class - you need to make wrapper slot:

class SomeController : public QObject
{
    Q_OBJECT
public slots:
    void processText(QString);
    {
        foo();
        bar();
    }
private:
    void foo();
    void bar();
};
  1. in your code you connecting to the processText signal, but your class SomeController doesn't have any signals

As suggested by ctinka, defining SomeController::processText as a signal is the right solution.

It is explicitly stated in the Qt Signals & Slots documentation that you may connect a signal to another signal:

It is even possible to connect a signal directly to another signal. (This will emit the second signal immediately whenever the first is emitted.)

Further considerations

Note that slots are normal C++ functions, so Qt is not able to perform any special logic (like calling the connected slots):

Slots are normal C++ functions and can be called normally; their only special feature is that signals can be connected to them.

On the other hand, signals are generated by Qt ( moc ) and therefore are able to call connected slots:

Signals are automatically generated by the moc and must not be implemented in the .cpp file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM