信号与槽机制
- 本质上就是观察者模式;
c
------------------------------------------
信号槽是Qt框架引以为豪的机制之一。
所谓信号槽,实际就是观察者模式。
当某个事件发生之后,
比如,按钮检测到自己被点击了一下,
它就会发出一个信号(signal)。
这种发出是没有目的的,类似广播。
如果有对象对这个信号感兴趣,它就会使用连接(connect) 函数,
意思是,将想要处理的信号和自己的一个函数(称为槽(slot))
绑定来处理这个信号。
也就是说,当信号发出时,被连接的槽函数会自动被回调。
这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。
------------------------------------------------------------------
自定义信号槽需要注意的事项:
------------------------------------------------------
发送者和接收者都需要是Q0bject的子类
(当然,槽函数是全局函数、Lambda表达式等无需接收者的时候除外); .
信号和槽函数返回值是void
信号只需要声明,不需要实现
槽函数需要声明也需要实现
槽函数是普通的成员函数,作为成员函数,
会受到public、 private、protected的影响;
使用emit在恰当的位置发送信号;
使用connect()函数连接信号和槽。
任何成员函数、static函数、全局函数和Lambda 表达式都可以作为槽函数
信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。
如果信号和槽的参数不-致,允许的情况是,槽函数的参数可以比信号的少,
即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起
来。这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数
的参数比信号的少)。
核心机制与常用控件
- Qt的优点:
- 1、跨平台;
- 2、接口的封装性好;
- 3、内部有一套内存回收机制;
- 4、轻量级的开发环境,可以做嵌入式开发;
c
语言:C++
----------------------------------------------------
信号与槽机制:
-----------------
connect函数
继承关系及框架
布局管理
------------------------------
Qt中常用的控件类:
------------------------
QPushButtons
QMainWindow
QDialog
模态和非模态
组合框
文件操作
------------
读文件:
---------
创建文件对象-------------文件路径
打开文件及方式
设定文件数据的二进制接收对象QByteArray
读取文件操作
readAll readLine...
关闭文件 close
---------------------
写文件:
--------------
有文件对象
打开文件及写文件的方式
写文件-----------write
关闭文件
-----------------
Qt中事件:
------------
Qt中事件机制:
-------------------
事件产生:
------------------
QApplication中产生接收系统中断信号产生QEvent事件对象
事件派发:
--------------------
由QApplication中调用notify()函数将事件派发到QObject中所有控件
事件的过滤:
-------------
eventFilter:
---------------
由具体控件执行,可重写这个函数、需要使用override
若没有重写eventFilter,默认是不过滤
-------------------------------------------------
事件的分发:
-------------------
event()函数
--------------------
对系统群发的事件进行分类
可以对事件类型分类,并由false交给系统处理,若是true,则交给个人处理;
事件的处理:
------------------
执行对事件的一些处理操作,
比如执行一些什么逻辑。
常用的QEvent类:
---------------------
QMouseEvent
QKeyEvent
QPaintEvent
QTimer定时器事件类
Qt中的Tcp通信
-----------------------------
QTcpServer
QTcpSocket
--------------------------------------------
Qt5基本模块:
-----------------------
QtNetwork
QtWidgets
QtWebEngins
QtChars
QtSQL
QtCore
QtGui
QtWebGL
QtQML
QtQuick
QtMulitmedia
-----------------------------------
Qt手册:
----------------------------------------------
先看类的描述,
再看所属模块,再看使用的头文件是那个,
再看继承关系(用来查相关方法)
-------------------------------------------
Qt中的坐标系(与笛卡尔坐标系的方向正好相反)及第一个交互控件:
------------------------------------------------------------------------------------
QPushButton
如果是最外层的控件,他的移动时的坐标以桌面左上顶点为原点(全局坐标系)。
如果是内嵌的控件,那么就是外层的控件的左上顶点为原点(局部坐标系)。
-----------------------------------------------
widget.cpp:
-----------------------------------------------------
//用刷子把图片刷到调色板上:
p.setBrush(QPalette::Window,QBrush(QPixmap("d:/Gril.png")));
this->setPalette(p);
//定义一个QPushBtton控件对象:
this->loginBtn = new QPushButton("登录",this);
//btn->setParent(this);
//相较于局部(父对象的坐标系)
this->loginBtn->move(10,10);
this->registorBtn = new QPushButton("注册",this);
//相较于局部(父对象的坐标系)
this->registorBtn->move(150,10);
//相较于全局的坐标系:
this->move(10,10);
--------------------------------------
widget.h:
---------------------------------------
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpServer>
#include <QPushButton>
class Widget : public QWidget
{
Q_OBJECT //用来支持信号与槽的。
public:
Widget(QWidget *parent = nullptr);//默认参数:父对象指针。
//用来自动回收子控件的资源的。
~Widget();//析构:
private:
QPushButton* loginBtn;
QPushButton* registorBtn;
};
#endif // WIDGET_H
-----------------------------------------------------------
main.cpp:
-----------------------------------------
#include "widget.h"
#include <unistd.h>
#include <QApplication>
//QApplication类是一个核心类:
//一个Qt工程有且只能有一个QApplication类对象。
//QApplication类对象是用来监控整个Qt工程中的控件的事件循环的。
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;//可展示的控件对象。
w.show();//控件对象渲染。
return a.exec();//由QApplication对象调用exec()进入到事件循环。
}
--------------------------------------
---------------------------------------------
Qt对象树内存回收机制:(纯C++展示对象树机制)
---------------------------------------------------------------
#include <iostream>
#include <list>
using namespace std;
class Object
{
public:
list<Object*> childList;
public:
Object(Object* parent = nullptr)
{
if(parent != nullptr)
{
parent->childList.push_back(this);
}
}
virtual ~Object()
{
for(Object* child : this->childList)
{
delete child;
}
}
};
class A : public Object
{
int* p;
public:
A(Object* parent = nullptr)
: Object(parent)
{
cout << "A的构造" << endl;
this->p = new int[1024];
}
~A()
{
if(this->p != nullptr)
{
delete [] this->p;
this->p = nullptr;
}
cout << "A的析构" << endl;
}
};
class B : public Object
{
int* p;
public:
B(Object* parent = nullptr)
: Object(parent)
{
cout << "B的构造" << endl;
this->p = new int[1024];
}
~B()
{
if(this->p != nullptr)
{
delete [] this->p;
this->p = nullptr;
}
cout << "B的析构" << endl;
}
};
int main()
{
//Object obj;
B b;
A* a = new A(&b);
return 0;
}
-------------------------------------------------------
总结:在Qt中如果使用对象一定是QObject的子类,不然无法使用对象树。