Qt信號槽使用方式

QT 信號槽connect寫法函數

先看下示例:this

QPushButton *btn = new QPushButton;

    // 方式一:老式寫法
    connect(btn, SIGNAL(clicked()), this, SLOT(close()));

    // 方式二:Qt5後新寫法
    connect(btn, &QPushButton::clicked, this, &MainWindow::close);

    // 方式三:lambda表達式
    connect(btn, &QPushButton::clicked, this, [&]() {
        this->close();
    });

方式一 老式寫法,在編譯的時候即便信號或槽不存在也不會報錯,可是在執行的時候無效,對於C++這種靜態語言來講,這是不友好的,不利於調試;指針

方式二 Qt5後推薦的寫法,若是編譯的時候信號或槽不存在是沒法編譯經過的,至關於編譯時檢查,不容易出錯,還有就是槽的寫法能夠直接寫在public控制域下,不必定非要寫在public slots:控制域下;調試

方式三 採用了lambda表達式的寫法,更加方便快捷。code

關於lambda須要注意一點:生命週期

QTimer::singleShot(3000, /* this, */ [&]{
        this->close();
    });

connect(btn, &QPushButton::clicked, /* this, */ [&]() {
        this->close();
    });

看下上面的示例,當咱們用lambda表達式的時候,槽的接收者QObject是能夠省略不寫的,這時候Qt會默認發射者與接收者屬於同一個QObject;io

//connect to a functor
    template <typename Func1, typename Func2>
    static inline typename std::enable_if<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::type
            connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
    {
        return connect(sender, signal, sender, slot, Qt::DirectConnection);
    }

當咱們省略槽函數接收者QObject時,那咱們就必需要注意lambda內成員的生命週期;例如示例的singleShot,若在槽函數響應前,this已經銷燬變爲無效指針,後果就會很嚴重!!!編譯

爲何?class

咱們知道,connect的發射者與接收者任意一個銷燬,那麼這個connect就已經斷開了;當咱們省略接收者QObject的時候,發射者與接收者屬於同一個QObject;在上面的示例中,信號槽connect關聯依然存在,信號槽依然會觸發,但此時this已經被銷燬cli

相關文章
相關標籤/搜索