【问题标题】:Qt forward slot / connect slot to slot?Qt正向插槽/将插槽连接到插槽?
【发布时间】:2017-06-17 11:10:50
【问题描述】:

我遇到了在接收信号后必须调用对象槽的情况(只需将信号转发到另一个对象槽)。我知道我可以简单地实现插槽并从正文中调用另一个插槽,但也许我可以用更简单的方式来做到这一点?

这里是示例代码:

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)

编辑:

好的,也许我的问题不够清楚 - 考虑到我的例子 - 我不想直接连接 SomeWidget 和 SomeUtil,因为我想隐藏我什至使用 SomeUtil 的事实。此类对于SomeController 的用户应该是不可见的。这是一个封装问题。 SomeController 是一种门面。

而且我不需要实现SomeController 的槽。唯一的工作就是调用SomeUtil的槽(转发信号)。

【问题讨论】:

  • 您可以在 SomeController 类中声明信号,将信号相互连接,以及小部件何时发出 textChanged 信号 - 您的控制器也会发出 processText 信号
  • @ctinka 确实可以,但我不认为这是一个很好的解决方案。信号被认为是“说”而不是“听”的功能。
  • 在 Qt 库中可以将信号连接到另一个信号

标签: c++ qt signals-slots


【解决方案1】:

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

【讨论】:

    【解决方案2】:
    1. 回答您的问题:您可以一个接一个地建立两个连接,并且插槽将以相同的顺序被调用 像

      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();
    };
    
    1. 在您的代码中您连接到 processText 信号,但您的类 SomeController 没有任何信号

    【讨论】:

      【解决方案3】:

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

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

      甚至可以将一个信号直接连接到另一个信号。 (这将在第一个信号出现时立即发出第二个信号 发射。)

      进一步考虑

      注意槽是普通的C++函数,所以Qt不能执行任何特殊的逻辑(比如调用连接的槽):

      槽是普通的C++函数,可以正常调用;他们唯一的 特点是可以连接信号。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-11
        • 1970-01-01
        • 2015-06-09
        • 1970-01-01
        • 2012-10-15
        • 1970-01-01
        • 1970-01-01
        • 2020-03-12
        相关资源
        最近更新 更多