控件的基本使用

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

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

窗口设置

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// 设置窗口标题
setWindowTitle("主窗口"); // 设置窗口大小
// 窗口可以通过拖拽边缘进行自由伸缩
// resize(400, 400); // 设置窗口的固定大小
// 窗口不能通过拖拽边缘进行自由伸缩
setFixedSize(400, 400); // 设置窗口的位置
// 以父控件的左上角为坐标原点
// 没有父控件,就以屏幕的左上角作为坐标原点
move(100, 100);
}

Qt坐标系如下图所示。

添加子控件

#include <QPushButton>

// 创建按钮
QPushButton *btn = new QPushButton;
// 设置按钮的文字
btn->setText("登录");
// 设置父控件为当前窗口
btn->setParent(this);
// 设置按钮的位置和大小
btn->move(50, 50);
btn->resize(100, 50); // 创建第2个按钮
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函数可以将信号的发送者信号信号的接收者连接在一起。

connect(信号的发送者, 信号, 信号的接收者, 槽);

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

自定义信号与槽

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

信号的发送者

  • sender.h

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

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

信号的接收者

  • receiver.h

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

连接

  • mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H #include <QMainWindow>
#include "sender.h"
#include "receiver.h" class MainWindow : public QMainWindow
{
Q_OBJECT
private:
Sender *_sender;
Receiver *_receiver;
void test1(); public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
};
#endif // MAINWINDOW_H
  • mainwindow.cpp
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
this->_sender = new Sender;
this->_receiver = new Receiver; // 连接
connect(this->_sender,
&Sender::exit,
this->_receiver,
&Receiver::handleExit); // 发出信号
// 最终会调用Receiver::handleExit函数
emit this->_sender->exit();
} MainWindow::~MainWindow()
{ }

参数和返回值

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

  • 发信号时的参数会传递给槽
  • 槽的返回值会返回到发信号的位置
// 自定义信号
signals:
int exit(int a, int b); // 自定义槽
public slots:
int handleExit(int a, int b); int Receiver::handleExit(int a, int b)
{
// Receiver::handleExit() 10 20
qDebug() << "Receiver::handleExit()" << a << b;
return a + b;
} // 发出信号
int a = emit this->_sender->exit(10, 20);
// 30
qDebug() << a;

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

// 自定义信号
signals:
void exit(int a); // 自定义槽
public slots:
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信号
connect(this->_sender,
&Sender::exit,
this->_sender2,
&Sender2::exit2);

Lambda

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

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

【秒懂音视频开发】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. &#128218;C#/.NET/.NET Core推荐学习书籍(升职加薪,你值得拥有)

    前言: 作为一名程序员,我们无时无刻都要考虑着如何通过不断地学习来提升自己的核心竞争力.古人有云:"书中自有黄金屋,书中只有颜如玉",说明了书籍的重要性,没错工作多年来,发现身边那 ...

  2. spark 一、编程指南

    总览 第一.每个spark 应用都有一个驱动程序去运行着主函数和再每个节点上的并行操作. spark提供了一个RDD(弹性分布式数据集)的数据集合,可以通过不同的节点并行操作运算,可以通过hdfs文件 ...

  3. MySQL5.6 与 MySQL5.7 的区别

    目录 编译安装区别 初始化的区别 其他区别 编译安装区别 # 5.7在编译安装的时候多了一个 boost 库 [root@db02 mysql-5.7.20]# yum install -y gcc ...

  4. 鸟哥的linux私房菜——第五章学习(Linux的文件权限与目录配置)

    ******************第五章学习****************** 1.[重要的三个概念] 1).文件拥有者(使用者):User,该文件/文件夹只能我来读写: 2).群组:Group, ...

  5. springboot demo(一)快速开始

    快速入门 maven构建项目 1.访问http://start.spring.io/ 2.选择构建工具Maven Project.Spring Boot版本2.26以及一些工程基本信息,点击" ...

  6. HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解

    题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...

  7. SSL 数据加密原理简述

    最近调试mqtt协议,为了保证数据安全性和将来客户端的对云的兼容性选择了openssl作为安全加密中间层,而没有使用私有的加密方式.所以花了点时间学习了一下ssl 加密流程整理如下: 因为正常正式使用 ...

  8. map & forEach

    map & forEach let logs = `2018-05-23 20:24:09,876 [Timer-2] ERROR org.gil.sydb.server.table.sync ...

  9. OAuth 2.0 All In One

    OAuth 2.0 All In One 授权类型 授权代码 隐式 密码凭证 客户端凭证 授权码 授权码授予类型要求用户向提供者进行身份验证-然后将授权码发送回客户端应用程序,提取并与提供者交换以获取 ...

  10. js & regex & var & highlight

    js & regex & var & highlight let key = `ali`.toLocaleUpperCase(); let name = "阿里云计算 ...