Qt如何转发槽函数/将一个槽函数连接到另一个槽函数?

4
我需要在接收信号后调用对象的插槽(只需将信号转发到其他对象的插槽)。我知道可以简单地实现插槽并从主体中调用另一个插槽,但也许我可以用更简单的方法来做?
以下是示例代码:
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)

编辑:

好的,也许我的问题不够清楚 - 就我所举的例子而言 - 我不想直接将SomeWidgetSomeUtil连接起来,因为我想隐藏我使用SomeUtil的事实。这个类应该对SomeController的用户是不可见的。这是封装的一个问题。 SomeController是一种外观。

更重要的是我不需要实现SomeController的槽。它的工作只是调用SomeUtil的槽(转发信号)。


1
你可以在你的 SomeController 类中声明信号,将信号连接起来,当小部件发出 textChanged 信号时,你的控制器也会发出 processText 信号。 - ctinka
@ctinka,我确实可以这样做,但我不认为这是一个好的解决方案。信号被认为是“说话”的函数,而不是“听取”的函数。 - Mariusz Jaskółka
在Qt库中,将一个信号连接到另一个信号是可以的。 - ctinka
3个回答

0
回答你的问题:你可以逐个建立两个连接,槽函数将按照相同的顺序被调用,就像这样:
connect(someWidget, &SomeWidget::textChanged, someController, &SomeController::processText);
connect(someWidget, &SomeWidget::textChanged, anotherController, &SomeController::processText);

如果您需要调用多个插槽,这将非常有用:

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

但是如果您需要调用同一类的私有成员函数 - 您需要创建包装器槽:

class SomeController : public QObject
{
    Q_OBJECT
public slots:
    void processText(QString);
    {
        foo();
        bar();
    }
private:
    void foo();
    void bar();
};

在你的代码中,你连接了processText信号,但是你的SomeController类没有任何信号。

0

你可以将信号连接到两个插槽上,它们都会被调用,并按照你连接它们的顺序执行。


0

根据ctinka的建议,将SomeController::processText定义为信号是正确的解决方案。

Qt Signals & Slots documentation明确指出,您可以将一个信号连接到另一个信号:

甚至可以直接将一个信号连接到另一个信号。 (这将立即发射第二个信号,每当第一个信号被发射时。)

进一步考虑

请注意,插槽是普通的C++函数,因此Qt无法执行任何特殊逻辑(如调用连接的插槽):

插槽是普通的C++函数,可以正常调用;它们唯一的特殊功能是信号可以连接到它们。

另一方面,信号由Qt(moc)生成,因此能够调用连接的插槽:

信号由moc自动生成,不得在.cpp文件中实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接