Qt的入门基础

音视频合集

1.Qt入门基础
2.音频基础
3.Mac环境安装FFmpeg和Qt
4.命令行操控音频
5.代码操控音频
6.播放PCM文件
7.PCM转WAV
8.WAV播放
9.音频重采样
10.AAC编码
11.手动编译ffmpeg
12.AAC编码实战
13.AAC 解码实战
14.YUV
15.录音视频
16.H264编码实战
17.H264解码
18.视频解码成yuv和pcm

1.Qt入门基础

1.1 控件的基本使用

从上一个文章Mac环境搭建的时候,可以看到创建工程的时候,是帮我们创立了了一个form 的文件,这个文件里面包含了一个可视化的ui,我们可以直接在里面拖拽控件,类似于iOS的故事板,为了更好的了解qt的控件,这里我们创建的时候,不勾选Generate form这一个选项,然后再.cpp文件中,代码创建控件


不勾选Generate form.png

对比图.png
1.2 窗口设置

代码


       //设置窗口标题
       setWindowTitle("主窗口");
       //设置窗口大小,可以自由拖动
       resize(600,600);
       //设置窗口的固定大小,窗口不能通过拖拽边缘进行自由伸缩
//       setFixedSize(600,600);
       //设置窗口的位置,以父控件的左上角为坐标原点,没有父控件的情况,就以屏幕的左上角作为坐标原点
       move(200,200);

效果图


设置窗口大小效果图.png
1.3 添加子控件

代码

  // 创建按钮
       QPushButton *btn = new QPushButton;
       // 设置按钮的文字
       btn->setText("登录");
       // 设置父控件为当前窗口
       btn->setParent(this);
       // 设置按钮的位置和大小
       btn->move(50, 50);
       btn->resize(100, 50);

       // 创建第2个按钮
       new QPushButton("注册", this);

效果图

按钮添加.png

2. 信号与槽

2.1 基本概念
  • 信号:泛指某一行为,例如说点击按钮时候会发出一个信号
  • 槽(Slot): 也叫槽函数,用来处理信号的函数
    官方文档
    signalAndSlot.png

    上面的大概意思是:
Object1发出信号signal1,交给Object2的槽slot1、slot2去处理
- 这个时候Object1是信号的发送者,Object2是信号的接收者

Object1发出信号signal2,交给Object4的槽slot1去处理
- Object1是信号的发送者,Object4是信号的接收者

Object3发出信号signal1,交给Object4的槽slot3去处理
- Object3是信号的发送者,Object4是信号的接收者

总结:1个信号可以由多个槽进行处理,1个槽可以处理多个信号
  • 信号的发送者、信号、信号的接收者、槽 之间的通信方式是通过connect函数
connect(信号的发送者, 信号, 信号的接收者, 槽);
 
// 比如点击按钮,关闭当前窗口
// btn发出clicked信号,就会调用this的close函数
connect(btn, &QPushButton::clicked, this, &MainWindow::close);
 
// 可以通过disconnect断开连接
disconnect(btn, &QPushButton::clicked, this, &MainWindow::close);

一个简单的案例

 btn->setText("关闭");
    btn->setFixedSize(100, 30);
    btn->setParent(this);
    // 连接信号与槽
    // 点击按钮,关闭MainWindow窗口
    // btn发出信号
    // MainWindow接收信号,调用槽函数:close
    connect(btn, &QPushButton::clicked,
            this, &MainWindow::close);

这个时候点击关闭,可以看到窗口就关闭了,这个就是信号与槽的概念了

2.2 自定义信号与槽

同一对象

  • Counter.h
#ifndef COUNTER_H
#define COUNTER_H

#include 

class Counter : public QObject
{
    Q_OBJECT
public:
    explicit Counter(QObject *parent = nullptr);

//    Counter() { m_value = 0; }

    int value() const { return m_value; }

public slots:
    void setValue(int value);

signals:
    void valueChanged(int newValue);

private:
    int m_value;
};

#endif // COUNTER_H

  • COunter.cpp
#include "counter.h"
#include 

Counter::Counter(QObject *parent) : QObject(parent)
{


}

void Counter::setValue(int value)
{
    if (value != m_value) {
        m_value = value;
         qDebug() << "Counter::setValue" << m_value;
        emit valueChanged(value);
    }
}

不同对象

  • 发送者
  • senderobj.h
#ifndef SENDEROBJ_H
#define SENDEROBJ_H

#include 

class SenderObj : public QObject
{
    Q_OBJECT
public:
    explicit SenderObj(QObject *parent = nullptr);

signals:
    //自定义信号
    void exit();

};

#endif // SENDEROBJ_H

  • senderobj.cpp
#include "senderobj.h"

SenderObj::SenderObj(QObject *parent) : QObject(parent)
{

}

  • 接受者
  • receiverobj.h
#ifndef RECEIVEROBJ_H
#define RECEIVEROBJ_H

#include 

class receiverObj : public QObject
{
    Q_OBJECT
public:
    explicit receiverObj(QObject *parent = nullptr);

//自定义槽
public slots:
    void handleExit();

};

#endif // RECEIVEROBJ_H

  • receiverobj.cpp
#include "receiverobj.h"
#include 

receiverObj::receiverObj(QObject *parent) : QObject(parent)
{

}


//实现槽函数,编写处理信号的代码
void receiverObj::handleExit(){
    qDebug() << "receiverobj::handleExit()";
}
  • 链接signal 和 slots
  • mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
};
#endif // MAINWINDOW_H

  • mainwidow.cpp
#include "mainwindow.h"
#include "counter.h"
#include "senderobj.h"
#include "receiverobj.h"

//https://doc.qt.io/qt-5/signalsandslots.html
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //创建对象
    SenderObj *sender = new SenderObj;
    receiverObj *receiver = new receiverObj;
    //连接
    connect(sender,&SenderObj::exit,receiver,&receiverObj::handleExit);

    //发出信号,最终会调用receiverobj::handleExit 函数
    emit sender->exit();
    //销毁对象
    delete sender;
    delete  receiver;
}


MainWindow::~MainWindow()
{
}

终端结果输出:

21:36:27: Starting /Users/songlin/audio/build-custom_signal_and_slot-Desktop_x86_darwin_generic_mach_o_64bit-Debug/custom_signal_and_slot.app/Contents/MacOS/custom_signal_and_slot ...
receiverobj::handleExit()

注意:参数解释

  • Q_OBJECT用以支持自定义信号和槽
  • 自定义的信号需要写在signals:下面
  • 自定义的信号只需要声明,不需要实现
  • 自定义的槽需要卸载slot:下面

刚刚上面示范了不同对象的自定义信号与槽,但是方法都是无参数,无返回值的,接下来我们可以看看有参数和有返回值的例子

  • sender.h
#ifndef SENDER_H
#define SENDER_H

#include 

class Sender : public QObject {
    Q_OBJECT
public:
    explicit Sender(QObject *parent = nullptr);

signals:
    int exit(int n1, int n2);
    void exit2(int n1, int n2);
};

#endif // SENDER_H

  • sender.cpp
#include "sender.h"

Sender::Sender(QObject *parent) : QObject(parent) {
}

  • receiver.h
#ifndef RECEIVER_H
#define RECEIVER_H

#include 

class Receiver : public QObject {
    Q_OBJECT
public:
    explicit Receiver(QObject *parent = nullptr);

public slots:
    int handleExit(int n1, int n2);
    void handleExit2(int n1, int n2);
};

#endif // RECEIVER_H

  • recever.cpp
#include "receiver.h"
#include 

Receiver::Receiver(QObject *parent) : QObject(parent) {
}

int Receiver::handleExit(int n1, int n2) {
    qDebug() << "Receiver::handleExit" << n1;
    return n1 + 20;
}

void Receiver::handleExit2(int n1, int n2) {
    qDebug() << "Receiver::handleExit2";
}

  • mainwindow.cpp
 Sender *sender = new Sender;
 Receiver *receiver = new Receiver;
connect(sender, &Sender::exit,
            receiver, &Receiver::handleExit);
    connect(sender, &Sender::exit2,
            receiver, &Receiver::handleExit2);
emit sender->exit(10, 20);

除开这种方式,还可以使用lambda的展示形式

  • mainwindow.cpp 之lambda连接
 Sender *sender = new Sender;
 Receiver *receiver = new Receiver;
//Lambda
 connect(sender, &Sender::exit, [](int n1, int n2) {
           qDebug() << "Lambda" << n1 << n2;
    });
    emit sender->exit(10, 20);

代码控件连接

 QPushButton *btn = new QPushButton;
    btn->setText("按钮");
    btn->setFixedSize(100, 40);
    btn->setParent(this);
    connect(btn, &QPushButton::clicked,
            this, &MainWindow::handleClick);
void MainWindow::handleClick() {
    qDebug() << "点击了按钮 - handleClick";
}

通过ui 文件建立signal 和 slot

新建一个工程叫做signal_slot_ui
进入到ui文件


Snip20210424_1.png

然后选中要操控的按钮->右键
Snip20210424_2.png

Snip20210424_3.png
Snip20210424_4.png

此时,Qt Creator已经帮你自动生成了槽函数的声明和实现,当我们点击登录按钮时,就会调用这个函数

  • mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_loginBtn_clicked();
    
    void on_registerBtn_clicked();
    
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

  • maindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_loginBtn_clicked()
{
    
}

void MainWindow::on_registerBtn_clicked()
{
    
}

为了方便看到测试结果,我们可以再实现方法那里写上打印信息

void MainWindow::on_loginBtn_clicked()
{
    qDebug() << "on_loginButton_clicked";
}

void MainWindow::on_registerBtn_clicked()
{
     qDebug() << "on_registerBtn_clicked";
}

最终可以看到我们点击按钮的时候,终端有了相应的输出

22:10:43: Starting /Users/songlin/audio/build-signal_sinal_ui-Desktop_x86_darwin_generic_mach_o_64bit-Debug/signal_sinal_ui.app/Contents/MacOS/signal_sinal_ui ...
on_loginButton_clicked
on_registerBtn_clicked

你可能感兴趣的:(Qt的入门基础)