首页 文章

Qt信号和插槽:权限

提问于
浏览
21

SO上的尊重答案与实际的Qt文档之间存在差异 .

我读过this question,我想进一步澄清一下 . 有人可以证实:

  • 信号总是 protected ,因此它只能由类或其任何子类发出 . 我不确定这是真的;上面的问题显示了支持这一陈述的答案 . 但Qt docs说: Signals are public access functions and can be emitted from anywhere, but we recommend to only emit them from the class that defines the signal and its subclasses. 那么这是什么?

  • 插槽只是功能,因此可以是公共的,私有的或受保护的 . 显然,如果插槽是公共的,那么外部类将能够控制您的类是否将其自身信号之一连接到其自己的插槽之一 . 但是,SO信息再次与文档不同,后者说: a signal emitted from an instance of an arbitrary class can cause a private slot to be invoked in an instance of an unrelated class. 这意味着 private 不受信号/槽机制的尊重?

  • 使用 signal 关键字时,public,private,protected这两个词没有用处

  • 发出的信号始终可用于所有其他类,也就是说,任何其他类可能始终连接到该信号(无论其发出信号的权限如何) .

  • 尽管所有类都可以查看所有信号,但由于 connect 函数将类名作为信号前缀(即 SomeClass::itsSignal ),因此您仍然可以使用两个具有相同名称信号的类 .

3 回答

  • 31
    • 信号在Qt4中受到保护,但在Qt5中是公开的,因此是矛盾的信息 .

    • 插槽是函数,public / protected / private在调用它们时受到尊重,当连接到信号时,元对象系统会忽略它 .

    • 由于 signals 被定义为 public: ,因此将它们添加到例如私人领导

    至:

    private:
    public: //signals:
        void theSignal();
    

    因此它没有效果 .

    • 所有类都可以连接到任何信号,正确无误 . 在这方面,信号是公共API的一部分 .

    • 具有相同的信号签名不是问题 . 上下文由指定为sender的对象定义 .

    使用旧式连接:

    Apple *apple ... Orange* orange
    connect(apple, SIGNAL(changed()), this, SLOT(appleChanged()));
    connect(orange, SIGNAL(changed()), this, SLOT(orangeChanged()));
    

    这里的信号被指定为字符串(没有类名),但是 appleorange 只有一个信号 changed() ,查找是在QObject实例的元对象中完成的,每个类(非实例)存在一个,他们不能碰撞 .

    带编译时检查的Qt 5版本:

    connect(apple, &Apple::changed, this, &MyReceiver::appleChanged);
    

    这里必须指定一个函数,因此根据范围,必须指定一个类名(可能还有名称空间) . 由于模糊函数名称不是有效的C而因此无法编译,所以这里安全 .

  • 0

    看一下 qobjectdefs.h (QT5.0) . 在那里定义了moc宏

    #     define signals public
    

    如您所见,信号头文件中使用的宏被定义为public . 至于显式statet public,private,protected指令,这些指令在信号部分被忽略 . 之前5.0版本的QT将信号定义为受保护 . 那些仍然可用于使用 SIGNAL() 宏的连接 .

    插槽宏

    #     define slots
    

    被定义为空宏,因此可以用于:

    public slots:
    private slots:
    protected slots:
    

    方法可见性用于直接方法调用,因此不能直接从外部类调用private / protected .

    使用a connect 语句仍然可以独立于可见性工作 . 这是预期的行为,并在moc生成的代码中实现 .

    如果我在Qt的早期版本中正确记得一个插槽也自动 public ,但我现在没有找到它的参考 .

    任何其他类都可以连接到来自外部类的信号,只要在类中给出Q_OBJECT宏并且已知外部类(包括头部) . 由于信号是按类定义的,因此在不同的类中使用相同的信号是完全合法的 . 这也很方便,例如在所有类中都有一个信号sendInfo(QString)使它更容易记忆 . Q_OBJECT宏使moc创建将信号连接到独立于可见性的插槽所需的代码 .

  • 4

    发出的信号始终可用于所有其他类,也就是说,任何其他类可能始终连接到该信号(无论其发出信号的权限如何) .

    在Qt5中,这不一定是真的 . 可以使用 QPrivateSignal 定义信号作为其最终参数,在这种情况下,只有声明信号的对象才能连接到它 .

相关问题