QThread

关于继承QThread线程对象在哪个线程中的判断,挺简单,只要记住对象在哪个线程中被创建存在,自身实例对象就在哪个线程中。
在Qt中一个对象的槽函数在被信号触发调用的时候,槽函数在那个线程中执行取决于它的对象属于那个线程中

默认情况一下我们在代码中创建的对象都属于主线程,这个对象的槽函数在调用的时候,占用的都是主线程的时间,我们也可以将一个QObject类型的对象或子类对象通过moveToThread移动到子线程中去,这样当这个对象的槽函数被信号触发调用的时候,槽函数占用的就是子线程的时间。
这个方法会更改此对象及其子对象的线程关联性。如果对象有父对象,则不能移动该对象。

槽函数可以跟任意线程的任意信号建立连接

在Qt中,QThread类用于创建和管理线程。QThread类提供了一个run()方法,该方法定义了线程要执行的任务。然而,直接调用run()方法并不会在一个单独的线程中执行,而是在当前线程中执行。这是因为QThread的run()方法实际上是一个普通的成员函数,而不是开启一个新的线程。

为了在一个单独的线程中执行任务,应该调用QThread的start()方法。start()方法会在一个新的线程中执行run()方法,从而实现并发执行。这是因为start()方法会在内部创建一个新的系统线程,并将run()方法在该线程中执行。

QDataStream数据流

QDataStream类用于将任意常见类型的数据以二进制写入到指定的目标中,同时也可以按写入的顺序从目标中读取这些类型的数据,实现数据的序列化。

这个操作在通信中很有用,例如:我需要将一个学生对象传递给对方,我只需通过QDataStream把学生对象序列化成一个二进制数据发送给对方,对方通过QDataStream反序列化就可以得到这个学生对象的数据。

数据流写入

当使用运算符重载<<或者使用writeBytes函数时写入QString QByteArray,QPicture,const char *类型的数据时,qt会自动在数据前面添加4个字节的长度信息。

QTextStream文本流

用法

1
2
3
4
5
6
7
8
9
10
QTextStream()  
QTextStream(QIODevice *device)
QTextStream(FILE *fileHandle,
QIODevice::OpenMode openMode = QIODevice::ReadWrite)
QTextStream(QString *string,
QIODevice::OpenMode openMode = QIODevice::ReadWrite)
QTextStream(QByteArray *array,
QIODevice::OpenMode openMode = QIODevice::ReadWrite)
QTextStream(const QByteArray &array,
QIODevice::OpenMode openMode = QIODevice::ReadOnly)

例子:

1
2
3
4
5
6
QFile data("output.txt");
if (data.open(QFile::WriteOnly | QFile::Truncate)) {
QTextStream out(&data);
out << "Result: " << qSetFieldWidth(10) << left << 3.14 << 2.7;
// writes "Result: 3.14 2.7 "
}

需要格外注意的是,如果使用了运算符重载<<进行数据写入,需要用.flush()方法来刷新缓存才能成功写入。

QString的使用

字符串拼接

QString对于很多运算符做了重载,可以直接用+号,或者.append方法,有时候想要用占位符替代的话,需要以下这种形式:

QString str1 = QString("%1---------------%2").arg("hello").arg(" world!");

这样输出str1的内容就是hello world!。

字符串长度计算

str1.size() / str1.count() / str1.length() 都可以,一个中文算一个字符。

字符串判断为空

.isNull() 只有当未被赋值的时候才为真,若 QString str1 = “”; 返回false
如果是.isEmpty() 返回真 ,若未被赋值, .isEmpty()也返回真

字符串提取子字符串

1
2
3
4
5
6
7
8
QString str;
QString csv = "forename,middlename,surname,phone";
QString path = "/usr/local/bin/myapp"; // First field is empty
QString::SectionFlag flag = QString::SectionSkipEmpty;

str = csv.section(',', 2, 2); // str == "surname"
str = path.section('/', 3, 4); // str == "bin/myapp"
str = path.section('/', 3, 3, flag); // str == "myapp"

qt-事件过滤器

作为事件过滤器的要求是QOject对象,监听的事件为QEvent的对象。
事件过滤器对象需要重写eventFilter()函数。函数的参数不需要自己传,目标对象会自动传,前提是使用了installEventFilter函数。

顺序容器

vector有多个构造函数,默认的构造函数是构造一个初始长度为0的内存空间,且分配的内存空间是以2的倍数动态增长的,在push_back的过程中,若发现分配的内存空间不足,则重新分配一段连续的内存空间,其大小是现在连续空间的2倍,在将原先空间中的元素复制到新的空间中,性能消耗较大。
vector在尾端增添数据拥有比较好的性能。
vector内部实现实际上是动态数组。分配好了一块内存空间。

如果你需要高效的随机存取,而不在乎插入和删除的效率,使用vector

如果你需要大量的插入和删除,而不关心随机存取,则应使用list

如果你需要随机存取,而且关心两端数据的插入和删除,则应使用deque

非类型参数

非类型参数只能是整数、枚举类型、指向外部链接的指针

非类型参数不能是一个浮点类型和类类型

抽象类

包含有纯虚函数的类称作抽象类
纯虚函数
‘virtual void Test(void)=0;’
基类不需要实现函数,提供模板为子类使用。
抽象类不能创建对象,因为纯虚函数没有实现功能。
可以作为引用或者指针的类型。
子类继承抽象类时必须实现抽象类里面的全部纯虚函数,否则子类也为抽象类