如何在不使用连接功能的情况下连接信号和插槽?

时间:2017-08-10 09:39:42

标签: c++ qt qt4 qt-signals qt-slot

有没有办法在不使用连接功能的情况下连接信号和插槽?

如果有办法,请举一些例子。

2 个答案:

答案 0 :(得分:4)

不,没有其他办法,至少在公共API中没有。在Qt4中,只有connect()函数包含SIGNAL()SLOT宏()。

在Qt5中,您有另一种类型安全的连接语法,但它仍然使用connect()函数。在QML中,您可以使用“附加处理程序” - onSignal: doStuff() - 但这仅适用于QML。

答案 1 :(得分:0)

有一种方法可以使用元调用接口来避免使用connect()函数。取决于您确切需要做什么,虽然这可能不是您正在寻找的解决方案,或者可能是。

你基本上用一定的语法在QOBJECT类中定义一个回调槽功能,然后让MOC对“连接”进行排序。进行。

所以说你想用:

connect(ui->actionButton, SIGNAL(triggered()), this, SLOT(someCallbackSlot()));

但无需使用回调函数......

您可以使用QOBJECT中接收信号的成员函数的特定语法隐式执行此操作:

class MyQtObj : public QWidget
{
QObject

private slots:

void on_actionButton_triggered();

}

其中on_actionButton_triggered是someCallbackSlot()的功能等价物,actionButton是按钮/动作/信号发射器的名称,triggered()是发出的信号。

因此,只要信号发射器正确,任何这些功能都是有效的:

void on_minimizedButton_clicked();

void on_closeButton_released();

当您运行Qt元对象编译器并生成此类的moc_.cpp文件时,将会有一个名为qt_static_metacall的函数;这包含一个如下所示的switch语句:

void MyQtObj::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
    if (_c == QMetaObject::InvokeMetaMethod) {
        MyQtObj*_t = static_cast<MyQtObj*>(_o);
        Q_UNUSED(_t)
        switch (_id) {
        case 0: _t->on_actionButton_triggered(); break;
        default: ;
        }
    }
}

如果您在此处设置断点并触发操作/按钮/信号,您应该会看到您的功能被执行。

我不太确定这是如何工作的细节,当我使用this frame-less Qt window code并在我自己的Qt C ++项目中采用它时我注意到了它。