信号和槽,以及qt连接中的一些基础知识点

1、凡是QObject类(不管是直接子类还是间接子类),都应该在第一行代码写上Q_OBJECT许多初学者会遇到莫名其妙的错误,一加上Q_OBJECT就出错,很大一部分是因为没有注意到这个宏应该放在头文件中

信号和槽,以及qt连接中的一些基础知识点_第1张图片

这个宏的展开将为我们的类提供信号槽机制、国际化机制以及 Qt 提供的不基于 C++ RTTI 的反射能力。

2、可以lambda表达式来替代槽函数。

3、

    (1)、在QT5中,槽函数可以不放在由slots修饰的代码块中。

//!!! Qt5
#include 

// newspaper.h
class Newspaper : public QObject
{
    Q_OBJECT
public:
    Newspaper(const QString & name) :
        m_name(name)
    {
    }

    void send()
    {
        emit newPaper(m_name);
    }

signals:
    void newPaper(const QString &name);

private:
    QString m_name;
};

// reader.h
#include 
#include 

class Reader : public QObject
{
    Q_OBJECT
public:
    Reader() {}

    void receiveNewspaper(const QString & name)
    {
        qDebug() << "Receives Newspaper: " << name;
    }
};

// main.cpp
#include 

#include "newspaper.h"
#include "reader.h"

int main(int argc, char *argv[])       //将执行程序时的两个命令行参数传入
{
    QCoreApplication app(argc, argv); //实例化一个应用

    Newspaper newspaper("Newspaper A");
    Reader reader;
    QObject::connect(&newspaper, &Newspaper::newPaper,
                     &reader,    &Reader::receiveNewspaper);
    newspaper.send();

    return app.exec();
}

    (2)在 Qt 4 中,槽函数必须放在由 slots 修饰的代码块中,并且要使用访问控制符进行访问控制。其原则同其它函数一样:默认是 private 的,如果要在外部访问,就应该是 public slots;如果只需要在子类访问,就应该是 protected slots。

//!!! Qt4
#include 

// newspaper.h
class Newspaper : public QObject
{
    Q_OBJECT
public:
    Newspaper(const QString & name) :
        m_name(name)
    {
    }

    void send() const
    {
        emit newPaper(m_name);//const函数不能调用非const函数
    }

signals:
    void newPaper(const QString &name) const;

private:
    QString m_name;
};

// reader.h
#include 
#include 

class Reader : public QObject
{
    Q_OBJECT
public:
    Reader() {}

public slots:
    void receiveNewspaper(const QString & name) const
    {
        qDebug() << "Receives Newspaper: " << name;
    }
};

// main.cpp
#include 

#include "newspaper.h"
#include "reader.h"

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    Newspaper newspaper("Newspaper A");
    Reader reader;
    QObject::connect(&newspaper, SIGNAL(newPaper(QString)),
                     &reader,    SLOT(receiveNewspaper(QString)));
    //QObject::connect(&newspaper, SIGNAL(newPaper(const QString)&),
    //                 &reader, SLOT(receiveNewspaper(const QString&)));  
    newspaper.send();
    return app.exec();
}

(3)成员初始化列表

            Newspaper(const QString & name):m_name(name)

      C++ 语法, m_name(name) 作用相当于在构造函数中添加这么一句:m_name = name。但是,初始化列表的执行是在构造函数的实际语句之前进行的。

 

    另外,构造函数为什么要使用const QString & name?这是标准C++中的内容,表明该参数是一个引用,并且函数不改变参数的值。

 

    (4)槽函数修饰public、private等

    public、private 这样的访问修饰符是供编译器检查的,对于运行期连接的信号槽,不会受到这些修饰符的影响。

    在qt5中,作为槽,始终是public的;

    在qt4中,connect()函数中使用成员函数作为槽函数时,会无视 private 限定符(即,你可以在 connect() 函数中将信号与 private 的槽函数连接起来,这不会报错)。当然,你也可以使用 private 修饰槽函数,只是这个 private 修饰符只在直接调用函数时起作用。

     (5)QApplication:QCoreAppilication:QObject

        QApplication:支持GUI应用

        QCoreApplication:仅仅支持控制台应用

        新建GUI项目时,会在main.cpp中自动生成:

                       QApplication app(argc,argv);

    (6)

    Qt 4 的 SLOT 和 SIGNAL 宏在处理之前有一个“标准化”的步骤,会将参数的 const 和引用都去除,只有一个最简单的类型作为参数,所以下面两种写法的结果其实是一样的。

QObject::connect(&newspaper, SIGNAL(newPaper(QString)),
&reader, SLOT(receiveNewspaper(QString)));

QObject::connect(&newspaper, SIGNAL(newPaper(const QString)&),
&reader, SLOT(receiveNewspaper(const QString&)));

 

4、 QT控制台与纯 C/C++ 的控制台程序的区别

       他们的一个很大的区别在 main() 函数的最后一句:return a.exec();

      Qt 会开启一个事件循环,监听程序发出的事件;普通 C/C++ 控制台程序,除非你自己编写事件循环,否则是没有这个实现的。

5、qt项目路径不允许出现中文

6、用QT创建了A、B两个窗体,准备把B中的信号发到A中的槽里,若不适用主函数,则应该把connect函数写在哪里?

    信号槽主要用于解耦,发出信号的对象不应该知道是谁使用了这个信号;基于这个原则,connect() 函数应该在槽函数的类中。所以按照这个案例,应该是在 A 中更合适一些。

7、信号和槽的参数传递的机制

    (1)当信号与槽函数的参数数量相同时,它们参数类型要完全一致。

    (2)当信号的参数与槽函数的参数数量不同时,只能是信号的参数数量多于槽函数的参数数量,且前面相同数量的参数类型应一致,信号中多余的参数会被忽略。

    (3)此外,在不进行参数传递时,信号槽绑定时也是要求信号的参数数量大于等于槽函数的参数数量。这种情况一般是一个带参数的信号去绑定一个无参数的槽函数。

你可能感兴趣的:(qt)