一、什么是信号与槽
信号(Signal)就是在特定情况下被发射的事件,例如 PushButton 最常见的信号就是鼠标
单击时发射的 clicked() 信号。
槽(Slot)就是对信号响应的函数。槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
举个例子:
对应于下图:老师是发送者,让一个学生回答问题(发出信号),学生就是接收者,需要回答问题(槽)。
********************************************************************************
可以在ui_mainwindow中查看到一下代码:
QObject::connect(pushButton, SIGNAL(clicked()), MainWindow, SLOT(close()));
其作用就是将 pushButton 按钮的 clicked() 信号与窗体(MainWindow)的槽函数 close() 相
关联,这样,当单击 pushButton 按钮(就是界面上的“X”按钮)时,就会执行 MainWindow
的 close() 槽函数。
三、编写函数连接信号与槽
信号与槽关联是用 QObject::connect() 函数实现的,其基本格式是:
QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
由于QObject是所有Qt类的基类,所以调用connect函数的时候不需要加QObkect::
① 使用connect函数连接pushButton和MainWindow
修改mainWindow.cpp如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(close()));
}
MainWindow::~MainWindow()
{
delete ui;
}
关于this的用法,this到底是指谁?
上述代码在MainWindow的构造函数中,实现了发送者pushButton,信号clicked(),this指针指向MainWindow,槽close()的连接。
Qt提供了一个绝妙的属性系统。Qt属性系统基于元数据对象系统--就是那个提供了对象内置信号和槽通讯机制的家伙。
Q_PROPERTY()是一个宏(批处理自定义脚本),用来在一个类中声明一个属性property,由于该宏是qt特有的,需要用moc进行编译,故必须继承于QObject类。
这是Q_PROPERTY的整体结构
1 Q_PROPERTY(type name
2 READ getFunction
3 [WRITE setFunction]
4 [RESET resetFunction]
5 [NOTIFY notifySignal]
6 [DESIGNABLE bool]
7 [SCRIPTABLE bool]
8 [STORED bool]
9 [USER bool]
10 [CONSTANT]
11 [FINAL])
下面是一些典型的声明属性的示例:
1 Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue)
2 Q_PROPERTY(bool animation READ getAnimation WRITE setAnimation)
3 Q_PROPERTY(QColor barColor READ getBarColor WRITE setBarColor)
常用(1)定义(2)只读read(3)写入write(4)通知notify
一个属性的行为就像类的数据成员,但是它还具有附加的特性,这些特性可以被元数据对象系统操作。这些特性是:
(2)需要一个READ访问器函数。用于读属性的值。理想情况下,有一个不变的函数用于此目的,并且它必须返回属性的类型的值或指针或引用。例如,QWidget::focus是一个只读的属性,它对应一个读函数:QWidget::hasFocus()。
(3)一个可选的WRITE访问器函数。它用于设置属性的值。它必须返回空并且至少具有一个参数,参数是属性类型的值或指针或引用。例如:QWidget::enabled具有WRITE函数QWidget::setEnable()。只读属性不需要写函数。例如,QWidget::focus没有对应的写函数。
一个可选的RESET函数。用于设置属性的值到它的默认值。例如:QWidget::cursor具有典型的READ和WRITE函数,QWidget::cursor()和QWidget::setCursor(),并且它也具有一个RESET函数,QWidget::unsetCursor()。RESET函数必须返回void并且不带有任何参数。
(4)一个可选的NOTIFY信号。如果被定义了,信号将在属性的值改变时发出。信号必须带有一个参数,这个参数的类型必须与属性相同;参数保存的是属性的新值。
示例: QString key = “Hello”; key = “World”; // 可以修改字符串的值
总结: const QString key表示key是一个不可修改的常量字符串,而QString key表示key是一个可修改的字符串。根据具体需求选择合适的声明方式。
1.定义
在Qt中,QVariant是一个通用的值容器,它可以存储任意类型的数据,例如整数、字符串、列表等等。它的主要作用是提供一种通用的数据类型,方便在不同的函数、类、模块之间传递数据。
2、QVariant对象的使用
QVariant对象的使用非常简单,主要包括以下几个方面:
2.1、存储数据:可以通过构造函数、赋值操作符、setValue函数等方法将数据存储到QVariant对象中。例如:
QVariant v1 = 10; // 存储整数
QVariant v2 = "hello"; // 存储字符串
QVariant v3 = QList() << 1 << 2 << 3; // 存储整数列表
2.2、获取数据:可以通过toXXX函数将QVariant对象转换为指定类型的数据。例如:
int n = v1.toInt(); // 将整数转换为int类型
QString str = v2.toString(); // 将字符串转换为QString类型
QList list = v3.toList(); // 将整数列表转换为QList类型
2.3、判断数据类型:可以使用type函数判断QVariant对象中存储的数据类型。例如:
if (v1.type() == QVariant::Int) {
// v1中存储的是整数
}
2.4、清空数据:可以使用clear函数清空QVariant对象中存储的数据。例如:
v1.clear(); // 清空v1中存储的数据
3、QVariant对象的完整示例代码
下面是一个简单的示例代码,演示了如何使用QVariant对象存储和获取数据:
二、使用
普通变量
QVariant var1;
var1.setValue(12);
int data1 = var1.toInt();
qDebug() << data1;
QVariant var2 = 14;
int data2 = var2.toInt();
qDebug() << data2;
打印
结构体
#include
#include
#include
#include
struct MyClass {
int id;
QString name;
};
Q_DECLARE_METATYPE(MyClass)
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyClass myClass;
myClass.id = 0;
myClass.name = QString("LiMing");
QVariant var3;
var3.setValue(myClass); //设置QVariant的值
qDebug() << "var3:" << var3;
MyClass stu; //这部分代码主要是将QVariant类再转化为MyClass类,其他QVariant类转化成其他类也可用这种方法
stu = var3.value();
qDebug() << "stu:" << stu.id << stu.name;
return a.exec();
}
保存指针
//保存
QVariant var = QVariant::fromValue((void*)event);
//获取
QPaintEvent* pointer = (QPaintEvent*)var.value();
三、源码
打开QVariant的定义,我们看到它使用了C++的联合
struct Private
{
union Data
{
char c;
uchar uc;
short s;
signed char sc;
ushort us;
int i;
uint u;
long l;
ulong ul;
bool b;
double d;
float f;
qreal real;
qlonglong ll;
qulonglong ull;
QObject *o;
void *ptr;
PrivateShared *shared;
} data;
uint type : 30;
uint is_shared : 1;
uint is_null : 1;
};
支持的类型
enum Type {
Invalid = QMetaType::UnknownType,
Bool = QMetaType::Bool,
Int = QMetaType::Int,
UInt = QMetaType::UInt,
LongLong = QMetaType::LongLong,
ULongLong = QMetaType::ULongLong,
Double = QMetaType::Double,
Char = QMetaType::QChar,
Map = QMetaType::QVariantMap,
List = QMetaType::QVariantList,
String = QMetaType::QString,
StringList = QMetaType::QStringList,
ByteArray = QMetaType::QByteArray,
BitArray = QMetaType::QBitArray,
Date = QMetaType::QDate,
Time = QMetaType::QTime,
DateTime = QMetaType::QDateTime,
Url = QMetaType::QUrl,
Locale = QMetaType::QLocale,
Rect = QMetaType::QRect,
RectF = QMetaType::QRectF,
Size = QMetaType::QSize,
SizeF = QMetaType::QSizeF,
Line = QMetaType::QLine,
LineF = QMetaType::QLineF,
Point = QMetaType::QPoint,
PointF = QMetaType::QPointF,
RegExp = QMetaType::QRegExp,
RegularExpression = QMetaType::QRegularExpression,
Hash = QMetaType::QVariantHash,
EasingCurve = QMetaType::QEasingCurve,
Uuid = QMetaType::QUuid,
ModelIndex = QMetaType::QModelIndex,
PersistentModelIndex = QMetaType::QPersistentModelIndex,
LastCoreType = QMetaType::LastCoreType,
Font = QMetaType::QFont,
Pixmap = QMetaType::QPixmap,
Brush = QMetaType::QBrush,
Color = QMetaType::QColor,
Palette = QMetaType::QPalette,
Image = QMetaType::QImage,
Polygon = QMetaType::QPolygon,
Region = QMetaType::QRegion,
Bitmap = QMetaType::QBitmap,
Cursor = QMetaType::QCursor,
KeySequence = QMetaType::QKeySequence,
Pen = QMetaType::QPen,
TextLength = QMetaType::QTextLength,
TextFormat = QMetaType::QTextFormat,
Matrix = QMetaType::QMatrix,
Transform = QMetaType::QTransform,
Matrix4x4 = QMetaType::QMatrix4x4,
Vector2D = QMetaType::QVector2D,
Vector3D = QMetaType::QVector3D,
Vector4D = QMetaType::QVector4D,
Quaternion = QMetaType::QQuaternion,
PolygonF = QMetaType::QPolygonF,
Icon = QMetaType::QIcon,
LastGuiType = QMetaType::LastGuiType,
SizePolicy = QMetaType::QSizePolicy,
UserType = QMetaType::User,
LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
构造函数
列出关于QVariant的所有用法。
QJson是一个基于Qt的开发包用来将JSON数据解析成QVariant对象,JSON的数组将被映射为QVariantList实例,而其他对象映射为QVariantMap实例。
Qt-学习 QJson协议解析_qt json-CSDN博客
1.1 Json的定义
JSON(JavaScrip Object Notation)是一种轻量级的数据交换格式。它基于ECMAScript(欧洲计算机协会订制的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得JSON成为理想的数据交换语言。易于人阅读和缩写,同时也易于机器解析和生成,并有效地提升网络传输效率。
简述:Json是一种数据格式,和语言无关,什么语言中都可以使用Json。基于这种通用的数据格式,一般处理两方面的任务:
1.组织数据(数据序列化),用于数据的网络传输。
2.组织数据(数据序列化),写磁盘文件实现数据的持久化存储(一般.json作为作为文件后缀)
Json中主要有两种数据格式:Json数组和Json对象,并且这两种格式可以交叉嵌套使用,下面一次介绍这两种数据格式:
字符串要写到双引号(“”)里边。
Json数组中嵌套Json数组,父子关系
Json数组嵌套Json对象,Json对象可以嵌套Json数组
(1)Json数组中的元素数据类型一致
[1, 2, 3] //整型
["哈哈","hehe","yiyi"] //字符串
(2)Json数组中的元素数据类型不一致
[1, 2, 3, true, false, "haha",null]
(3)Json数组中的数据嵌套使用
[
["cat", "狗狗", "河马", 1]//元素类型可以不一致
[1, 3, 5, true]
]
(4)Json数组和Json对象嵌套
Json对象写入Json数组,数组是父节点,对象是子节点,Json对象下的Json对象是三级节点(Key:value)。"小明"是key值,{ }是小明的value值,属性是键值对
例如:Json数组,小明(Json对象),年龄、父亲、姐姐(属性键值对)
[//外层是Json数组
{//内层是Json对象
"小明":{//属性键值对
"age":19,
"father":"大华",
"sister":"小妹",
"sister1":"大妹" //sister键值不可以重复
}
}
]
*** 键值key,必须是字符串,位于同一层级的键值,不能重复(通过键值取出数据value)
*** value值的类型是可选的,整形,浮点型,字符串,json数组,json对象,空值-null(null)
使用Json对象描述一个人的信息:
{
"NAME":"ACE",
"Sex":"man",
"Age":20,
"Family":{
"Father":"yiyi",
"brother":["aa","bb","cc"]
},
"IsLive":"true"
}
数据简单放数组,数据更复杂放Json对象,数组和对象的嵌套使用可以更加完整描述模型!!!
错误示范:
bool类型 QJsonValue::Bool
double类型 QJsonValue::Double
string类型 QJsonVale::String
array类型 QJsonValue.:Array
object类型 QJsonValue:Object
null了下 QJsonValue::Null
类似于6种类型,放到一个箱子里面。
封装了Json中的对象,在里边可以存储多个键值对(K-V结构,key值是唯一的),为了方便操作,键值为字符串类型,值为QJsonValue类型,关于这个类的使用类似,C++中STL类 QJsonObject内数据使用insert插入,根据key值,自动排序,底层红黑树,升序
QJsonObject::QJsonObject() //构造空对象
iterator QJsonObject::insert(const QString &key, const QJsonValue &value);//key value
int QJsonObject::count() const;
int QJsonObject::size() const;
int QJsonObject::length() const;
传入key:得到QJsonObject对象,看看是什么,在使用to方法,得到原始数据
1、QJsonValue QJsonObject:: value(const QString &key) const; //utf-8
2、QJsonValue QJsonObject:: value(QLatin1QString key) const; //字符串不支持中文
3、QJsonValue QJsonObject:: operator[“ 这个括号里填写KEY值的字符串” ](const QString &key) const; //使用的时候["key值"]
4、QJsonValue QJsonObject:: operator[“ 这个括号里填写KEY值的字符串” ](QLatin1QString key) const;
void QJsonObject::remove(const QString &key);
QJsonValue QJsonObject::take(const QString &key); //删除键值对后,返回value值
iterator QJsonObject::find(const QString &key); //返回的是迭代器,解引用,可以得到数据value值 bool
QJsonObject::contains(const QString &key) const; //查看QJsonObject对象中,是否 存在这个key键值对
1.使用迭代器函数
2.使用[],遍历,类似遍历数组,[]中是key
3.先得到对象中所有的键值,在遍历键值列表,通过key得到value QStringList QJsonObject::keys() const;//得到当前Json对象中所有的key值
QStringList QJsonObject::keys() const;//得到当前Json对象中所有的key值
QJsonArray里面封装了Json数组,里面存储多个元素,为了方便操作,所有元素类型统一为QJsonValue类型
注意:QJsonArray内元素是无序的,完全按照添加顺序存储。
先添加,放在前面,后添加放在后面。插入,就放在插入的位置。
QJsonArray::QJsonArray() //得到空的Json数组,通过size()方法,返回值为0
void QJsonArray::append(const QJsonValue &value); //在尾部追加
void QJsonArray::insert(int i, const QJsonValue &value); //插入到i的位置之前
iterator QJsonArray::insert(iterator before, const QJsonValue &value); //在迭代器当前位置的前面,插入
void QJsonArray::prepend(const QJsonValue &value); //添加到数组头部
void QJsonArray::push_back(const QJsonValue &value); //添加到尾部
void QJsonArray::push_front(const QJsonValue &value); //添加到头部
int QJsonArray::count() const;
int QJsonArray::size() const;
iterator QJsonArray::erase(iterator it); //基于迭代器的删除
void QJsonArray::pop_back(); //删除尾部
void QJsonArray::pop_front(); //删除头部
void QJsonArray::removeAt(int i); //删除i位置元素
void QJsonArray::removeFirst(); //删除头部
void QJsonArray::removeLast(); //删除尾部
QJsonValue QJsonArray::takeAt(int i); //删除i位置的原始,并返回删除元素的值
QJsonObject是用于表示JSON对象的类,它类似于C++中的std::map或字典数据结构,可以使用键值对存储和访问数据。每个键都是唯一的,与每个值关联。QJsonObject内部以键值对的形式组织数据,其中键是字符串,值可以是字符串、数字、布尔值、其他JSON对象或JSON数组。
QJsonArray是用于表示JSON数组的类,它类似于C++中的std::vector或列表数据结构,可以按照索引顺序存储和访问数据。QJsonArray可以包含多个元素,每个元素可以是字符串、数字、布尔值、其他JSON对象或JSON数组。
if(settingJsonObject.contains(key))
settingJsonObject.contains(key))是一个条件语句,用于判断一个名为settingJsonObject的JSON对象中是否包含指定的键key。如果包含该键,则条件为真,执行相应的代码块;如果不包含该键,则条件为假,可以执行其他代码块或进行其他处理。
contains()是JSON对象的一个方法,用于检查该对象是否包含指定的键。key是要检查的键名。
const QJsonObject jsonObject = settingJsonObject.value(key).toObject()
定义一个常量的QJsonObject对象。它的初始化值是通过从settingJsonObject中获取key对应的值,并将其转换为QJsonObject类型。
这样,常量jsonObject就包含了settingJsonObject中key对应的QJsonObject值。
return m_cameraName[index];
是一行代码,它表示从一个名为 m_cameraName
的数组中返回指定索引 index
处的元素值。
这行代码的作用是获取 m_cameraName
数组中指定索引位置的相机名称,并将其作为返回值返回。根据索引的不同,可以获取到不同位置的相机名称。
int ListModel_Camera::getPosNum(const int index) {return m_posNum[index];}
int ListModel_Camera::getPosNum(const int index)
{return m_posNum[index]; }
是一个函数声明,它属于 ListModel_Camera
类。
函数的参数是一个整数 index
,表示要获取位置数值的索引位置。
函数的返回值是一个整型 int
,表示获取到的位置数值。
QList ListModel_Camera::getPositionsList(const int index) {
QList positionsList;
int posNum = m_posNum[index];
for(int i=1; i<=posNum; i++) {
positionsList.append(i);
}
return positionsList;
}
这是一个函数的定义,函数名为getPositionsList
,返回类型为QList
,参数为const int index
。函数的作用是根据传入的index`参数获取一个整数列表。
函数内部首先创建了一个空的整数列表positionsList
。然后通过访问m_posNum
数组获取到对应索引位置的整数值posNum
。接下来使用一个循环从1到posNum
,将每个整数依次添加到positionsList
中。最后将整数列表返回。
这个函数的作用是根据传入的索引值获取一个整数列表,列表中的元素从1到对应索引位置的整数值。
return m_cameraName.size();
返回m_cameraName数组的size大小
QVariant ListModel_Camera::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
// FIXME: Implement me!
if (index.row() < 0 || index.row() >= m_cameraName.count())
return QVariant();
switch (role) {
case CameraNameRole:
return m_cameraName.value(index.row());
case PtzRole:
return m_ptz.value(index.row());
case IPRole:
return m_ip.value(index.row());
case PortRole:
return m_port.value(index.row());
case SerialPortRole:
return m_serialPort.value(index.row());
case ChnPortRole:
return m_chn.value(index.row());
case OutputRole:
return m_output.value(index.row());//摄像机
case PosNumRole:
return m_posNum.value(index.row());//特技机
default:
return QVariant();
}
}
QVariant ListModel_Camera::data(const QModelIndex &index, int role) const是一个函数的声明,它属于ListModel_Camera类。这个函数的作用是返回指定索引和角色的数据。
函数的参数有两个:
函数的返回类型是QVariant,它是Qt框架中的一个通用数据类型,可以存储各种不同类型的数据。
在函数体内部,你需要根据索引和角色来确定要返回的数据。具体的实现逻辑需要根据你的具体需求来确定,可以根据索引和角色从相应的数据源中获取数据,并将其封装成QVariant类型后返回。
迭代式的执行,每个case语句中执行结束后再继续执行下一个分支
QLatin1String是Qt框架中的一个类,用于处理Latin-1编码的字符串。它提供了一种轻量级的方式来处理Latin-1编码的字符串,同时避免了内存分配和复制的开销。
QLatin1String的主要特点如下:
使用QLatin1String时需要注意以下几点:
m_orderVector.reserve(count);
m_orderVector.reserve(count)是C++中的一个函数调用,它用于预留容器的存储空间,以便在不重新分配内存的情况下存储更多的元素。
具体来说,m_orderVector是一个容器(比如std::vector),而reserve()是该容器的成员函数。它接受一个整数参数count,表示要预留的元素数量。
当调用reserve(count)时,容器会分配足够的内存空间来存储至少count个元素。这样做的好处是,在后续添加元素时,不需要频繁地重新分配内存,从而提高了性能。
需要注意的是,reserve()只会分配内存空间,并不会真正添加元素到容器中。如果要添加元素,还需要使用push_back()等函数。
while(++ m_currentStep < m_enabledVector.size() +1 )
m_currentStep
:这是一个变量,表示当前的步骤数。m_enabledVector.size()
:这是一个容器(例如vector)的成员函数,返回容器中元素的数量。+1
:这是一个加法操作,将m_enabledVector.size()
的结果加1。整个表达式的含义是,如果当前步骤数加1小于等于容器中元素的数量加1,则表达式的结果为真(true),否则为假(false)。
在C++中,&符号用于获取变量的地址。在这个函数中,&byteArray表示获取参数byteArray的地址,并将该地址作为参数传递给waitSend函数。这样做的目的是为了避免在函数调用时进行大量的数据拷贝,提高程序的效率。通过获取参数的地址,可以直接在函数内部操作原始数据,而不需要创建新的副本。