控件的基本使用

为了更好地学习Qt控件的使用,建议创建项目时先不要生成ui文件。

打开mainwindow.cpp,在MainWindow的构造函数中编写界面的初始化代码。

窗口设置

  1. MainWindow::MainWindow(QWidget *parent)
  2. : QMainWindow(parent)
  3. {
  4. // 设置窗口标题
  5. setWindowTitle("主窗口");
  6. // 设置窗口大小
  7. // 窗口可以通过拖拽边缘进行自由伸缩
  8. // resize(400, 400);
  9. // 设置窗口的固定大小
  10. // 窗口不能通过拖拽边缘进行自由伸缩
  11. setFixedSize(400, 400);
  12. // 设置窗口的位置
  13. // 以父控件的左上角为坐标原点
  14. // 没有父控件,就以屏幕的左上角作为坐标原点
  15. move(100, 100);
  16. }

Qt坐标系如下图所示。

添加子控件

  1. #include <QPushButton>
  2. // 创建按钮
  3. QPushButton *btn = new QPushButton;
  4. // 设置按钮的文字
  5. btn->setText("登录");
  6. // 设置父控件为当前窗口
  7. btn->setParent(this);
  8. // 设置按钮的位置和大小
  9. btn->move(50, 50);
  10. btn->resize(100, 50);
  11. // 创建第2个按钮
  12. new QPushButton("注册", this);

new出来的Qt控件是不需要程序员手动delete的,Qt内部会自动管理内存:当父控件销毁时,会顺带销毁子控件。

信号与槽

基本使用

  • 信号(Signal):比如点击按钮就会发出一个点击信号
  • 槽(Slot):一般也叫槽函数,是用来处理信号的函数
  • 官方文档参考:Signals & Slots

上图中的效果是:

  • Object1发出信号signal1,交给Object2的槽slot1、slot2去处理

    • Object1是信号的发送者,Object2是信号的接收者
  • Object1发出信号signal2,交给Object4的槽slot1去处理
    • Object1是信号的发送者,Object4是信号的接收者
  • Object3发出信号signal1,交给Object4的槽slot3去处理
    • Object3是信号的发送者,Object4是信号的接收者
  • 1个信号可以由多个槽进行处理,1个槽可以处理多个信号

通过connect函数可以将信号的发送者信号信号的接收者连接在一起。

  1. connect(信号的发送者, 信号, 信号的接收者, 槽);
  2. // 比如点击按钮,关闭当前窗口
  3. // btn发出clicked信号,就会调用this的close函数
  4. connect(btn, &QAbstractButton::clicked, this, &QWidget::close);
  5. // 可以通过disconnect断开连接
  6. disconnect(btn, &QAbstractButton::clicked, this, &QWidget::close);

自定义信号与槽

信号的发送者和接收者都必须继承自QObject,Qt中的控件最终都是继承自QObject,比如QMainWindow、QPushButton等。

信号的发送者

  • sender.h

    • Q_OBJECT用以支持自定义信号和槽
    • 自定义的信号需要写在signals:下面
    • 自定义的信号只需要声明,不需要实现
  1. #ifndef SENDER_H
  2. #define SENDER_H
  3. #include <QObject>
  4. class Sender : public QObject
  5. {
  6. Q_OBJECT
  7. public:
  8. explicit Sender(QObject *parent = nullptr);
  9. // 自定义信号
  10. signals:
  11. void exit();
  12. };
  13. #endif // SENDER_H
  • sender.cpp
  1. #include "sender.h"
  2. Sender::Sender(QObject *parent) : QObject(parent)
  3. {
  4. }

信号的接收者

  • receiver.h

    • 自定义的槽建议写在public slots:下面
  1. #ifndef RECEIVER_H
  2. #define RECEIVER_H
  3. #include <QObject>
  4. class Receiver : public QObject
  5. {
  6. Q_OBJECT
  7. public:
  8. explicit Receiver(QObject *parent = nullptr);
  9. // 自定义槽
  10. public slots:
  11. void handleExit();
  12. };
  13. #endif // RECEIVER_H
  • receiver.cpp
  1. #include "receiver.h"
  2. #include <QDebug>
  3. Receiver::Receiver(QObject *parent) : QObject(parent)
  4. {
  5. }
  6. // 实现槽函数,编写处理信号的代码
  7. void Receiver::handleExit()
  8. {
  9. qDebug() << "Receiver::handleExit()";
  10. }

连接

  • mainwindow.h
  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. #include "sender.h"
  5. #include "receiver.h"
  6. class MainWindow : public QMainWindow
  7. {
  8. Q_OBJECT
  9. private:
  10. Sender *_sender;
  11. Receiver *_receiver;
  12. void test1();
  13. public:
  14. MainWindow(QWidget *parent = nullptr);
  15. ~MainWindow();
  16. };
  17. #endif // MAINWINDOW_H
  • mainwindow.cpp
  1. #include "mainwindow.h"
  2. MainWindow::MainWindow(QWidget *parent)
  3. : QMainWindow(parent)
  4. {
  5. this->_sender = new Sender;
  6. this->_receiver = new Receiver;
  7. // 连接
  8. connect(this->_sender,
  9. &Sender::exit,
  10. this->_receiver,
  11. &Receiver::handleExit);
  12. // 发出信号
  13. // 最终会调用Receiver::handleExit函数
  14. emit this->_sender->exit();
  15. }
  16. MainWindow::~MainWindow()
  17. {
  18. }

参数和返回值

信号与槽都可以有参数和返回值:

  • 发信号时的参数会传递给槽
  • 槽的返回值会返回到发信号的位置
  1. // 自定义信号
  2. signals:
  3. int exit(int a, int b);
  4. // 自定义槽
  5. public slots:
  6. int handleExit(int a, int b);
  7. int Receiver::handleExit(int a, int b)
  8. {
  9. // Receiver::handleExit() 10 20
  10. qDebug() << "Receiver::handleExit()" << a << b;
  11. return a + b;
  12. }
  13. // 发出信号
  14. int a = emit this->_sender->exit(10, 20);
  15. // 30
  16. qDebug() << a;

需要注意的是:信号的参数个数必须大于等于槽的参数个数。比如下面的写法是错误的:

  1. // 自定义信号
  2. signals:
  3. void exit(int a);
  4. // 自定义槽
  5. public slots:
  6. void handleExit(int a, int b);

连接2个信号

比如下图,连接了Object 1的Signal 1A和Object 2的Signal 2A

  • 当Object 1发出Signal 1A时,会触发Slot X、Slot Y
  • 当Object 2发出Signal 2A时,只会触发Slot Y,而不会触发Slot X

可以利用connect函数连接2个信号

  • 当_sender发出exit信号时,_sender2会发出exit2信号
  • 当_sender2发出exit2信号时,_sender并不会发出exit信号
  1. connect(this->_sender,
  2. &Sender::exit,
  3. this->_sender2,
  4. &Sender2::exit2);

Lambda

也可以直接使用Lambda处理信号。

  1. connect(this->_sender, &Sender::exit, []() {
  2. qDebug() << "lambda handle exit";
  3. });

【秒懂音视频开发】05_Qt开发基础的更多相关文章

  1. 【秒懂音视频开发】02_Windows开发环境搭建

    音视频开发库的选择 每个主流平台基本都有自己的音视频开发库(API),用以处理音视频数据,比如: iOS:AVFoundation.AudioUnit等 Android:MediaPlayer.Med ...

  2. 【秒懂音视频开发】26_RTMP服务器搭建

    从本节开始,正式开启流媒体相关的内容. 流媒体 基本概念 流媒体(Streaming media),也叫做:流式媒体. 是指将一连串的多媒体数据压缩后,经过互联网分段发送数据,在互联网上即时传输影音以 ...

  3. 从零到一,使用实时音视频 SDK 一起开发一款 Zoom 吧

    zoom(zoom.us) 是一款受到广泛使用的在线会议软件.相信各位一定在办公.会议.聊天等各种场景下体验或者使用过,作为一款成熟的商业软件,zoom 提供了稳定的实时音视频通话质量,以及白板.聊天 ...

  4. 【音视频连载-001】基础学习篇- SDL 介绍以及工程配置

    技术开发故事会连载 这是音视频基础学习系列的第一篇文章,主要讲解 SDL 是什么以及为什么要用到它,看似和音视频没啥卵关系,其实必不可少. SDL 简介 SDL 是 "Simple Dire ...

  5. 【秒懂音视频开发】23_H.264编码

    本文主要介绍一种非常流行的视频编码:H.264. 计算一下:10秒钟1080p(1920x1080).30fps的YUV420P原始视频,需要占用多大的存储空间? (10 * 30) * (1920 ...

  6. 【秒懂音视频开发】14_AAC编码

    AAC(Advanced Audio Coding,译为:高级音频编码),是由Fraunhofer IIS.杜比实验室.AT&T.Sony.Nokia等公司共同开发的有损音频编码和文件格式. ...

  7. 【秒懂音视频开发】18_详解YUV

    本文的主角是多媒体领域非常重要的一个概念:YUV. 简介 YUV,是一种颜色编码方法,跟RGB是同一个级别的概念,广泛应用于多媒体领域中. 也就是说,图像中每1个像素的颜色信息,除了可以用RGB的方式 ...

  8. 【秒懂音视频开发】12_播放WAV

    对于WAV文件来说,可以直接使用ffplay命令播放,而且不用像PCM那样增加额外的参数.因为WAV的文件头中已经包含了相关的音频参数信息. ffplay in.wav 接下来演示一下如何使用SDL播 ...

  9. 【秒懂音视频开发】21_显示BMP图片

    文本的主要内容是:使用SDL显示一张BMP图片,算是为后面的<播放YUV>做准备. 为什么是显示BMP图片?而不是显示JPG或PNG图片? 因为SDL内置了加载BMP的API,使用起来会更 ...

随机推荐

  1. Codeforces Round #544 (Div. 3) E. K Balanced Teams (DP)

    题意:有\(n\)个人,每个人的能力值是\(a_i\),现在你想将这些人分成\(k\)组(没必要全选),但是每组中最高水平和最低水平的人的能力差值必须\(\le 5\),问最多能选多少人. 题解:想了 ...

  2. codeforces 5D

    D. Follow Traffic Rules time limit per test 1 second memory limit per test 64 megabytes input standa ...

  3. 最新 Vue 源码学习笔记

    最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...

  4. JavaScript Inheritance All in One

    JavaScript Inheritance All in One constructor inheritance prototype chain inheritance "use stri ...

  5. Windows 10 滚动截图工具

    Windows 10 滚动截图工具 Edge & Note & Clip https://www.runoob.com/docker/docker-architecture.html ...

  6. js & sort array object

    js & sort array object sort array object in js https://flaviocopes.com/how-to-sort-array-of-obje ...

  7. news of javascript

    news of javascript https://javascriptweekly.com/ https://javascriptweekly.com/issues https://www.inf ...

  8. moment.js & convert timestamps to date string in js

    moment.js & convert timestamps to date string in js https://momentjs.com/ moment().format('YYYY- ...

  9. windwos创建和删除服务

    创建 >sc create <service name> type=kernel binpath="C:\hsys.sys" 删除 win+r 输出 regedi ...

  10. hadoop环境搭建:完全分布式

    目录 1.硬件配置 2.软件版本 3.准备工作 3.1.建立虚拟机,网络设置为桥接模式 3.2.更改主机名 3.3.绑定主机名和IP,建立各主机间的联系 3.4.关闭防火墙 3.5.配置宿主机host ...