Qt记录

开启C++11支持

  1. .pro文件中增加:

    CONFIG += c++11
    

    或者

    QMAKE_CXXFLAGS += -std=c++11
    

    两种添加形式都是可行的,建议每个工程单独配置,而不要一劳永逸。

信号与槽

作为信号(signal)与槽(slot),我们的信号函数的参数个数可以多于槽函数的参数个数,也就是说,我们可以选择接受不多于信号函数参数个数的参数,有点绕:

  • 信号函数的类:

    class Signal_Class:public QObject{
    ...
    public:
    ...
        void Q_SendSignal()
        {
            emit Q_TestSignal(UserName, UserAge);
            //UserName, UserAge 是该类的私有属性。
        }
    signals:
        void Q_TestSignal(const QString & name);
        void Q_TestSignal(const QString & name, int age);
    // ...
    
- 对于这段代码而言,有两个地方需要注意,`emit`, `public signals:`

    - 此处故意令信号函数重载,是为了在后方体现,槽函数的参数个数可以小于或者等于信号函数的参数个数。
    - `emit` 就是发射信号的意思。
  • 槽函数的类:

    class Slot_Class:public QObject{
    ...
    public slots:
        void Q_TestSlot(const QString & name)
        {
             QMessageBox mesbox;
             mesbox.setText("Receive : "+name);
             mesbox.exec();
        }
    // ...
    
  • 测试:

    void (Signal_Class::* p_to_test)(const QString &, int) = 
         &Signal_Class::Q_TestSignal;
        //因为是重载函数,所以需要明确指明使用哪个作为连接的信号函数 
    QObject::connect(&test_sig, p_to_test,
                     &test_slot, Slot_Class::Q_TestSlot);
    test_sig.Q_SendSignal(); //发射信号
    

    效果图

我们会发现,即使槽函数的参数个数与信号函数不一致(小于),但是依然可以接收到参数,但是需要注意的是,虽然能够自由选择接受的参数,但是依旧需要按照顺序(按照C++语法上的顺序)。

既然槽函数能够接受不多于信号函数参数个数的参数,那么我们自然而然能够想到,是否可以使用让槽函数拥有默认参数,以此来扩大槽函数的适用范围,答案是可以。

  • 依旧是上方的代码,改动些许:

    • 信号函数的类改动

      void Q_SendSignal()
      {
          emit Q_TestSignal(UserName);
          //UserName 是该类的私有属性。
      }
      
    • 信号函数类改动

      void Q_TestSlot(const QString & name
                    , const QDate & time = QDate::currentDate())
      {
          //需要添加#include <QDebug>
          //如果接受成功,可在终端看到输出。
          qDebug() << name << time;
      }
      
    • 测试代码改动(关键点)
    • 在此刻我们需要让编译器知道,我们的信号函数是一个参数,而槽函数是两个参数,其中一个是带有默认参数的,我们应该怎么做?函数指针对于默认参数是无效的,那么除了使用C++11新特性Lambda匿名函数以外,最直接的还是使用宏SLOT 和 SIGNAL,在这里我们使用这两个宏可以节省很多工作量,缺点就是无法在编译时刻知道是否匹配,所以我们需要小心谨慎的使用。

      QObject::connect(&new_paper_1, SIGNAL(newPaper(QString)),
                      &new_reader_1, SLOT(receive_newpaper(QString)));
      

      可以看到,我们的槽函数明明有两个参数,但是此处SLOT宏内只出现了一个,这就表明已经告知编译器是默认参数。

  • Lambda 匿名函数在 connect 的应用

    • 再实在没有办法用其他方法实现两个窗口或者不同对象之间的直接对话时候,可以考虑使用信号槽来间接实现
    • Lambda 扮演的角色是让类更加简洁,语法更加简单。
    • 到了 Qt5 时代,在使用信号槽语法的时候,更多的是用函数指针地址,而不是之前的SIGNALSLOT 宏,这样更能充分的发挥 Lambda 的性质。

      class MainWindows::MainWindow():
      //... 一些自动生成的初始化
      {
          //...setup Ui
          connect(ui->pushButton, &QPushButton::clicked, [=](){
             ui->browser_show->setText(QStringLiteral("成功使用Lambda语法设置文本显示"));//一个槽
          ui->pushButton->setEnable(false);// 另一个槽
          qDebug << QStringLiteral("成功使用Lambda语法!");
      
          }
          ...
      }
      

      这是基本使用方式,好处就是可以一次性的调用多个槽,而不是一个connect只能对应一对信号槽链接。

老生常谈的 中文显示

  • 使用 UTF-8 模式存储源文件(借助其他编辑器,例如 NotePad++, Sublime Text 等)
  • 使用 QStringLiteral 包裹中文
  • 行了。

转载注明: www.wushxin.top/2015/06/12/Qt记录.html