控件的基本使用

为了更好地学习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. Educational Codeforces Round 97 (Rated for Div. 2) C. Chef Monocarp (DP)

    题意:有\(n\)个菜在烤箱中,每个时刻只能将一个菜从烤箱中拿出来,第\(i\)个时刻拿出来的贡献是\(|i-a[i]|\),你可以在任意时刻把菜拿出来,问将所有菜拿出的最小贡献是多少? 题解: 先对 ...

  2. Nginx基础 - 配置静态web服务

    1.静态参数配置1)文件读取高效sendfile Syntax: sendfile on | off; Default: sendfile off; Context: http, server, lo ...

  3. 【非原创】LightOJ-1274 Beating the Dataset【期望dp】

    学习博客:戳这里

  4. 关于rand()

    虽然很早就知道rand是伪随机了,但是一般都懒得用srand. 直到模拟银行家算法时不用srand就造成数据实在有点假(-_-||) 所以要记得srand((int)time(0))啊

  5. nextLine()和next()的区别和使用方法

    最近在笔试,刷剑指Offer时,都是只需要把方法实现了就行.但是!!!笔试时候会发现,大部分会要求你把main函数也code出来,真是醉了,第一次笔试时候搞的晕乎乎的..... 废话不多说,那么在写输 ...

  6. springboot( 三)redis demo

    redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结构,例如hashes, lists, sets等,同时支持数据持久化.除此之外,Red ...

  7. Install wx

    Ubuntu 16.04: 由于是PY交易, 实际上是安装wxPython: pip install -U \ -f https://extras.wxpython.org/wxPython4/ext ...

  8. ES6 Map to Array

    ES6 Map to Array function differentSymbolsNaive(str) { // write code here. const map = new Map(); co ...

  9. Big O Complexity Graph

    Big O Complexity Graph Big O === O() 算法复杂度速查表 数据结构 数组排序算法 Quicksort O(n log(n)) O(n log(n)) O(n^2) O ...

  10. react & redux data flow diagram

    react & redux data flow diagram Redux 数据流程图