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).
您可以将信号连接到两个插槽,然后按照连接的顺序将它们都调用。
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();
};
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.