【QT】大型工程关键技术总结:①类套类 ②多线程

【工程规范】

1 文件夹规范

每个核心模块代码放一个文件夹(方便 类版本迭代!)

-Yolo
--v1
---pri
---Yolo.pro
---yolo.h
---yolo.cpp
---Debug

项目文件夹

-Projects.pro

-debug

-module
--Yolo
--Halcon

-src
--yolo
---best.onnx

最终版本的pro

$$PWD表示 .pro所在文件夹
HEDERS += $$PWD/module/Yolo/v1/yolo.h
SOURCEs += $$PWD/module/Yolo/v1/yolo.cpp

每个pri

不管这个pri在哪里,所有地方直接include 头文件名字

注意:所有头文件名字唯一

INCLUDEPATH +=$$PWD

HEADERS += \
    $$PWD/mainwindow.h

SOURCES += \
    $$PWD/mainwindow.cpp

FORMS += \
    $$PWD/mainwindow.ui

2 类规范

全部是QMainwindos类

可以使用qt和C++的全部功能

命名规范

  • 类 *p_yolo
  • 变量 a_
  • 函数 DetectAndPass

(一)类套类

核心要义:面向对象编程

1. 1几十个Qt类

(pri嵌套大法)

 1. 按照你要的模块建立文件夹
 2. 对应的文件夹里面写一个.pri
 3. pro文件包含这个pri
 4. pri可以多级嵌套,从而实现模块嵌套
 如下图

在这里插入图片描述
pri文件写法
在这里插入图片描述

1.2类嵌套如何实现?

(一个类成为另一个类的成员变量即可,注意this)
所有类都是qt ui界面类(方便使用this指针实现父子关系,方便一起析构,你只要不调用show方法,ui文件不会有影响)

 
 例如,如何将B作为类A的成员:
 #include<B.h>
 class A
 {
 	B*  p_b=NULL;
 }
 void run()
 {
  p_b=new B(this);
  p_b->setAttribute(Qt::WA_DeleteOnClose); //确保同时析构
 }

1.3 一个类作为一个类的变量(this),怎么实现值传递?

目前是:A成员有个B,B成员有个C

1.3.1 C访问B,A

//c.cpp
#include "b.h"
#include "ui_b.h"
#include "a.h"
#include "ui_a.h"
//只能在cpp里面include!!
void C::on_pushButton_2_clicked()
{
    B *pbwin=(B *) parentWidget(); //定义一个指向B的指针
    int tmp1=pbwin->bnum;
    cout<<"bnum  "<<tmp1<<endl;
}

void C::on_pushButton_3_clicked()
{
    A *pawin=(A *) parentWidget()->parentWidget();
    int tmp2=pawin->anum;
    cout<<"anum  "<<tmp2<<endl;
}

1.3.2 A访问B,C

void A::show_c()
{
    int tmp =this->pb->pc->cnum;
    cout<<"cnum  "<<tmp<<endl;
}

(二)多线程

步骤:
  1. 写好一个类,发现类里面有个函数比较复杂,需要多线程
  2. 类里使用lamda表达式创建一个关于该函数的线程,用的时候调用,然后detach即可
detach的理解:

1.detach后的线程谁也管不了了,他会一直运行,直到执行完代码。
2.所以这里的要注意有没有死循环,注意给他flag,让他退出循环,从而他可以执行完代码然后结束线程。

2.1 第一种情况::你只是执行一个会一路到底不会循环的耗时函数

    void run()
    {
        do complicate work;
    }
    std::thread t()
    {
        return std::thread([=]{run();});
    }
    
    //开始启动多线程工作
    void start()
    {
	    std::thread th=t();
	    th.detach();
    }

2.2 第二种情况:你要运行一个while(1)循环,不断做某事

由于detach是孤儿线程,你要定义一个flag,告诉它是时候退出while循环了,

那么跳出while循环后,他会执行完下面的代码,执行完了,这个线程就自动结束了

例如关闭一个mainwindow窗口,会发送一个qcloseevent消息
    void closeEvent(QCloseEvent *event)
    {
        qDebug()<<"close event!!";
        close_flag=1;
    }
    你的while循环根据这个close_flag来退出循环

(三)类之间传递数据

3.1 全局变量(放弃)

能不用就不用,就一司马玩意!!

所有.h文件里写:
extern std::string msg;

某一个.cpp文件里写:
std::string msg;

所有引用了这个头文件的cpp文件里就都可以使用msg这个全局变量了。
亲测:全局Mat有bug

3.2 parent指针

1.3

3.3 自定义消息变量

1 每一个类带一个自定义消息

2 每一个类带一个槽函数

3 利用emit signal slot机制传递数据
四个类

w1

signals:
    void w1_signal_null();
    void w1_signal_int(int a);
    void w1_signal_int_int(int a,int b);

public slots:
    void w1_slot_int(int a)
    {
        if(n1!=a)
        {
            n1=a;
        }
    }
    void w1_slot_int_int(int a,int b)
    {
        if(n1!=a)
        {
            n1=a;
        }
        if(n2!=b)
        {
            n2=b;
        }
    }

w2

signals:
    void w2_signal_null();
    void w2_signal_int(int a);
    void w2_signal_int_int(int a,int b);

public slots:
    void w2_slot_int(int a)
    {
        qDebug()<<"rec:"<<a;
        if(n1!=a)
        {
            n1=a;
        }
    }
    void w2_slot_int_int(int a,int b)
    {
        qDebug()<<"rec:"<<a<<" "<<b;
        if(n1!=a)
        {
            n1=a;
        }
        if(n2!=b)
        {
            n2=b;
        }
    }

w3

win2 *p_win2=new win2(this);

mainwin

win1 *w1 = new win1(this);
win3 *w3 = new win3(this);

初始化函数里面
connect(w1,SIGNAL(w1_signal_int(int)),(w3->p_win2),SLOT(w2_slot_int(int)));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值