NO.9 C++ QT 入门

零蚀
[ QT官网]
[ QT download]


QT 配置

  • qt的cmake设置

    cmake_minimum_required(VERSION 3.13)
    project(QTDemo)
    
    # 自动调用moc,uic,rcc处理qt的扩展部分
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTORCC ON)
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    # 指定版本
    set(CMAKE_CXX_STANDARD 14)
    
    add_executable(QTDemo main.cpp)
    
    
    # 查找qt模块(qt编译核心库)
    find_package(Qt5Core)
    find_package(Qt5Gui)
    find_package(Qt5Widgets)
    
    
    # 链接库
    target_link_libraries(QTDemo Qt5::Widgets Qt5::Core Qt5::Gui)
    
    • moc 做预处理,信号和槽需要的宏定义需要将其打开;
    • uic 处理UI拖拽,将界面变为C++操作
    • rcc 处理代码目录
    • include current dir 包含当前目录
  • qt的创建

    C++的qt设置和pyqt5的设置方式基本一致

    main.cpp

    #include 
    #include 
    
    int main(int argc,char *argv[]) {
    
        // 创建一个QApplication程序
        QApplication app(argc,argv);
        MainWindow w;
        w.setContent();
        w.show();
        return QApplication::exec();
    }
    

    MainWindow.h

    #ifndef QTDEMO_MAINWINDOW_H
    #define QTDEMO_MAINWINDOW_H
    
    
    #include 
    
    class MainWindow: public QWidget {
    public:
        explicit MainWindow(QWidget* qWidget= nullptr);
        ~MainWindow() override ;
    
        void setContent();
    };
    
    
    #endif //QTDEMO_MAINWINDOW_H
    

    MainWindow.cpp

    #include 
    #include "MainWindow.h"
    
    MainWindow::MainWindow(QWidget *qWidget):QWidget(qWidget) {
    
    }
    MainWindow::~MainWindow() {
    
    }
    
    void MainWindow::setContent() {
        this->setWindowTitle("C++的第一个QT应用");
    }
    

    NO.9 C++ QT 入门_第1张图片


QT 信号和槽

  • 内存管理

    Qt的内存控制为半自动化的内存管理控制,不需要手动释放创建的控件的空间,子控件最好不能申请控件在栈中,其一,栈空间有限,其二不能通过栈来创建子控件控件对象,不显示。

    QT也是有内存树的关系,QT内的总父类为QObject,QObject内部会保存一个list,会储存children,还有一个指针会记录parent,当自己析构时,会将自己从parent列表中删除并且析构所有的children。(这里的parent是指contain)

    ⚠️影响对象内存的因素:成员变量,智能指针,虚函数(首次会有影响,由于首次指针影响。)

    由于栈的先进后出的缘故,会导致一些逻辑错误:

    QLabel label("Hello");
    QWidget w;
    label.serParent(w);
    
  • 内存泄漏

    如没有设置其父控件的对象,需要在界面关闭时候进行手动释放这个控件。

    方案一:

    QLabel *label=new QLabel("这是一个文本");
    // application退出时,手动释放
    int exec1 = QApplication::exec();
    delete label;
    return exec1;
    

    方案二:

    // 栈内存释放
    QLabel *label=new QLabel("这是一个文本");
    label->show();
    // 自动关闭堆内存
    label.setAttribute(Qt::WA_DeleteOnClose);
    
  • 信号和槽

    void MainWindow::setContent() {
        this->setWindowTitle("C++的第一个QT应用");
        this->setMinimumSize(800,600);
        QPushButton *button=new QPushButton("button",this);
    
    }
    

    button的点击监听

    // 槽函数
    void click_change() {
        std::cout << "sg" << std::endl;
    }
    // 信号和槽的设置
    /**
     *sender
     * signal
     * receiver
     * method
     */
    connect(button,&QPushButton::clicked,QApplication::instance(),click_change);// click()信号无参,槽函数无参
    

    自定义槽函数

    class MainWindow: public QWidget {
        Q_OBJECT // 宏定义
    public:
        explicit MainWindow(QWidget* qWidget= nullptr);
        ~MainWindow() override ;
    
        void setContent();
    
    public slots:
    /
        void click_change();
    
    };
    
    //------------------
    
    void MainWindow::setContent() {
        this->setWindowTitle("C++的第一个QT应用");
        this->setMinimumSize(800,600);
        auto *v_layout=new QHBoxLayout(this);
        QPushButton *button=new QPushButton("button",this);
        QLabel *label=new QLabel("点击之前",this);
        v_layout->addWidget(label);
        v_layout->addWidget(button);
    
        // 信号和槽的设置
        /**
         *sender
         * signal
         * receiver
         * method
         */
        // click()无参数信号,槽函数无参
    //    connect(button,&QPushButton::clicked,QApplication::instance(),click_change);// 槽函数无参
        connect(button,&QPushButton::clicked,this,&MainWindow::click_change);
    
    
    }
    // 槽函数
    void MainWindow::click_change() {
        std::cout << "sg" << std::endl;
    }
    

    lambda的应用

    connect(button,&QPushButton::clicked,this,[](){std::cout << "click" << std::endl;});
    // or 省略接收者
    connect(button,&QPushButton::clicked,[](){std::cout << "click" << std::endl;});
    // 当然也可以调用函数(python传参也是得用lambda)
    connect(button,&QPushButton::clicked,[]()->void{function("六六六");});
    
  • 自定义信号和槽

    构建信号(必须是继承QObject)

    // SignalWidget.h
    #ifndef QTDEMO_SIGNALWIDGET_H
    #define QTDEMO_SIGNALWIDGET_H
    
    
    #include 
    
    class SignalWidget: public QWidget {
        // 信号和槽的宏定义
        Q_OBJECT;
    public:
        SignalWidget(QWidget *qWidget=nullptr);
        ~SignalWidget();
    signals:
        // 定义信号,不需要实现
        void Signal_Func();
    };
    
    
    #endif //QTDEMO_SIGNALWIDGET_H
    //SignalWidget.cpp
    #include "SignalWidget.h"
    
    SignalWidget::SignalWidget(QWidget *qWidget):QWidget(qWidget) {
    
    }
    
    SignalWidget::~SignalWidget() {}
    

    创建槽(必须是继承QObject)

    // SlotWidget.h
    #ifndef QTDEMO_SLOTWIDGET_H
    #define QTDEMO_SLOTWIDGET_H
    
    
    #include 
    
    class SlotWidget:public QWidget {
        Q_OBJECT;
    public:
        SlotWidget(QWidget *qWidget=nullptr);
        ~SlotWidget();
    public slots:
        // 槽函数
        void Slot_Func();
    
    };
    
    
    #endif //QTDEMO_SLOTWIDGET_H
    
    // SlotWidget.cpp
    #include 
    #include "SlotWidget.h"
    
    void SlotWidget::Slot_Func() {
        std::cout << "信号" << std::endl;
    }
    
    SlotWidget::SlotWidget(QWidget *qWidget):QWidget(qWidget) {}
    
    SlotWidget::~SlotWidget() {}
    

    绑定和发送信息

    //MainWindow.h
    #include 
    #include 
    #include 
    
    class MainWindow: public QWidget {
        Q_OBJECT // 宏定义
    public:
        SignalWidget *signalWidget= nullptr;
        SlotWidget *slotWidget= nullptr;
    
    .....
    //MainWindow.cpp
    MainWindow::MainWindow(QWidget *qWidget) : QWidget(qWidget) {
        signalWidget=new SignalWidget(this);
        slotWidget=new SlotWidget(this);
    }
    ......
    
    void MainWindow::setContent() {
        //绑定信号和槽
        connect(signalWidget, &SignalWidget::Signal_Func, slotWidget, &SlotWidget::Slot_Func);
        //点击按钮发送信号
        connect(button, &QPushButton::clicked, [this]() -> void {
            emit this->signalWidget->Signal_Func();
        });
    
    
    }
    

    上述绑定和发送,都可以复数形式绑定和发送信息,从而达到多信息,多槽的模式。

    信号断开

    // 参数和绑定一致
    disconnect(signalWidget, &SignalWidget::Signal_Func, slotWidget, &SlotWidget::Slot_Func);
    
    

前言
C++ 高级列表
NO.1 C++ 基础
NO.2 C++ 指针
NO.3 C++ 特殊函数
NO.4 C++ 重载&继承&lambda
NO.5 C++ 虚函数&智能指针
NO.6 C++ I/O
NO.7 C++ 模版编程&容器
NO.8 C++ 常用函数&线程
NO.10 C++ QT 绘制&自定义组合控件
NO.11 C++ QT 绘制

你可能感兴趣的:(C++篇)