《Python基础教程》 笔记

Python具有丰富和强大的库

** 幂运算符 2**3
pow(2, 3)
abs(-10) 绝对值
round(1.0 / 2.0) 四舍五入到整数
import math 导入math模块
math.floor(32.9) –> 32
from math import floor
floor(32.9)

变量
x = 3

print(“Hello World!”)
x = input(“prompt:”)

转换为字符串
str 类型
repr 函数
str(1000L) -> 1000
repr(1000L) -> 1000L

拼接字符串
“Hello ” + “World!”
temp = 100
s = “Hello” + str(temp)

raw_input 100 -> ‘100’
input 100 -> 100
input Hello -> 当做变量
raw_input Hello -> ‘Hello’ 字符串

长字符串
“”” string “”” 保留换行,和特殊字符比如’ ”
”’ string ”’
原始字符串 不会转义,最后一个字符不能是\
r’Hello,\nWorld!’ -> ‘Hello,\nWorld’

Unicode字符串
u’Hello World’

基本类型
str int long

序列
a1 = [‘Hello’, 100]
str = ‘Hello’
str[0] -> ‘H’
str[-1] -> ‘o’
分片 第一二个参数分别是元素索引[index1, index2)
a1 = [1, 2, 3, 4, 5]
a1[0:3] -> [1,2,3]
a1[0:] -> 0到结尾
a1[:] -> 所有元素
a2[0:3:1] ->第三个参数步长,默认为1
序列连接
[1,2,3] + [4,5,6]
‘Hello ‘ + ‘World’
[1,2,3] + ‘Hello’ # Error,相同类型的序列才能相加
序列乘以数字n : 序列重复n次
‘python’ * 4
pythonpythonpythonpython
空序列
[]
[None] * 10 None表示什么都没有 类似c++中的NULL
判断是否在序列中
permissions = ‘rw’
‘w’ in permissions -> True
内建函数 len min max
len 返回序列中元素个数
min(2,4,6)
列表、元组属于序列
列表 可变序列
元组 不可变序列

元素赋值
x = [1, 1, 1]
x[1] = 2 -> [1, 2, 1]

删除元素
names = [‘Alice’, ‘Beth’, ‘Cecil’]
del names[2]

分片赋值
names[1:] = [‘a’, ‘b’]

list(‘Hello’) 转换为可变序列
names.append(‘Hello’)
names.count(‘Alice’) 元素出现的次数

list tuple str 类型
a.extend(b) 拼接,修改a
a.index(‘who’) 查找元素 返回索引,找不到将引发异常
a.insert(index, value)
a.pop(index) 移除,如果不指定index,删除最后一个
a.remove(value)
a.reverse()
a.sort()
sorted(a) 返回排序副本
内建比较函数 cmp()
cmp(100, 200) -> -1

元组
不能修改
1,2,3 -> (1,2,3)
(1,2,3) -> (1,2,3)
() 空元组
(42,) 包含一个值的元组
tuple 类型非函数 以一个序列作为参数并把它转换为元组
tuple([1,2,3]) -> (1,2,3)
tuple(‘abc’) -> (‘a’,’b’,’c’)
tuple((1,2,3)) -> (1,2,3)

字符串方法
find 没有找到返回-1
“With a moo-moo here, and a moo-moo there.”.find(‘moo’)
title = “Monty python”
title.find(‘Monty’)
table = maketrans(‘ABC’, ‘abc’)
word = ‘ABC’
word.translate(table)

字典
phonebook = {‘Alice’:’2341′, ‘Beth’:’9120}
空字典 {}

dict 类型 通过对其他映射或者(键值)这样的序列对建立字典
items = [(‘name’,’Gumby’), (‘age’,42)]
d = dict(items)
d = dict(name=’Gumby’, age=42)

基本字典操作
len(d)
d[k]
d[k] = v
del d[k]
k in d

import module
— module.function()
from module import function
— function()
import math as foobar
— foobar.sqrt(100)
from math import sqrt as foobar

同一行输出
print ‘Hello’,
print ‘world!’

比较运算符可以连接
0<age<100

== 值相等 可以比较序列的值
is 引用相等 (避免用于比较类似数值和字符串这类不可变值)

逻辑运算符
and or not

三元运算符 c中的 ? :
a = b and c or d
c if b else d

range(0, 10) 结果是一个序列

zip 函数
names = [‘anne’, ‘beth’, ‘george’, ‘damon’]
ages = [12, 45, 32, 102]
zip(names, ages)
[(‘anne’, 12), (‘beth’, 45), (‘george’, 32), (‘damon’, 102)]

函数 reversed sorted

循环的else子句 没有调用break时执行

列表推导式
[x*x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

#注释

字典 引用
a = None

什么都不做的语句 pass

删除名称
x = [“Hello”, “World]
del x

执行字符串中的Python代码
exec “print ‘Hello, world!'”
exec(“print ‘Hello, world!'”) #Python3.0

命名空间
from math import sqrt
scope = {}
exec ‘sqrt = 1’ in scope
sqrt(4) # ->2.0
scope[‘sqrt’] # ->1

eval 计算表达式值

函数是否可调用
callable(x)
Python3.0 hasattr(func, __call__)

定义函数
def hello(name):
return ‘Hello. ‘ + name + ‘!’

#注释

文档字符串 def语句后面、模块或者类的开头

help函数
help(square)

非位置参数(与位置无关)
调用函数时,指明参数名

参数默认值

*收集参数到元组

**收集关键字参数到字典

在调用函数时使用 * ** 将元组或字典解包成参数

vars() 返回当前作用域字典
globals() 返回全局作用域字典
locals()

给全局变量赋值
x = 1

闭包概念 类似lua

lambda表达式
lambda 数学中表示匿名函数
一切用递归实现的功能都可以用循环实现,但有时递归更易读。
递归的一个局限,有耗尽栈空间的风险。

map(func, seq) 对序列中的每个元素应用函数
filter(func, seq) 返回其函数为真的元素的列表

isinstance(object, tuple)
isinstance(object, dict)

#为变量随机赋值
from random import choice
x = choice([‘Hello, world!’, [1,2,’e’,’e’,4]])

repr函数 输出变量文本表示
x = ‘Fnord’
print repr(x)

type
isinstance
issubclass

创建类

类中的变量和self.变量不是同一个,前者所有实例共享,后者是实例的私有变量。

foo = Person() #创建实例
foo.setName(‘Hello’)
foo.greet()
Person.setName(foo, ‘Hello’)

私有实现方式
前面加__
但仍然可以访问
s._类名__函数名()

指定超类
class Filter:

class SPAMFilter(Filter):

issubclass(SPAMFilter, Filter) ->True

获取基类
SPAMFilter.__bases__
一个对象属于哪个类
s.__class__
type(s) # 使用__metaclass__=type 或从object继承

tc是否包含talk特性
hasattr(tc, ‘talk’)
是否可调用
callable(getattr(tc, ‘talk’, None))
Python3.0 hasattr(x, ‘__call__’)

术语
特性 成员变量
方法 成员函数

异常处理
异常类 从Exception继承
引发异常 raise Exception # 会自动创建实例
raise Exception(‘hyperdrive overload’)
内建异常 exceptions模块

dir函数 列出模块的内容
import exceptions
dir(exceptions)

最重要的内建异常类:146页

捕获异常

重新抛出捕获的异常
raise # 无参数

获得异常实例

Python3.0
except (ZeroDivisionError, TypeError) as e:
捕获所有异常

__future__
两边带下划线的被称为魔法或特殊方法
实现这些方法,这些方法会在特殊情况下被Python调用

构造函数

析构函数
__del__
因为有垃圾回收机制,所以避免使用__del__

调用父类的构造函数
方法1

方法2

静态方法 类成员方法

一个实现了__iter__方法的对象是可迭代的,一个实现了next方法的对象则是迭代器。

内建函数iter可以从可迭代的对象中获得迭代器
it = iter([1,2,3])
it.next() ->1
it.next() ->2

将迭代器或迭代对象转换为序列
ti = TestIterator()
list(ti) -> […]

任何包含yield语句的函数称为生成器

生成器是逐渐产生结果的复杂递归算法的理想实现工具。

–第10章–
充电时刻
import sys
sys.path.append(‘c:/python’)
告诉解释器除了从默认的目录中寻找之外,还需要从目录c:/python中寻找模块
.py .pyw (windows系统)
.pyc 平台无关的 经过处理(编译)的,已经转换成Python能够更加有效地处理的文件。
导入模块的时候,其中的代码被执行。重复导入,不会重复执行。
强制重新导入 reload(hello) # hello – 模块名 Python3.0已经去掉

.py 文件 导入后文件名就是模块名作用域

主程序 __name__ -> ‘__main__’
import __name__ -> ‘__模块名__’
模块中的测试代码可以使用__name__判断是否执行测试代码。

pprint模块中pprint函数 提供更加智能的打印输出,比如列表分行输出。
sys.path
PYTHONPATH 环境变量

包 – 目录
目录中包含__init__.py文件

查看模块包含的内容可以使用dir函数,他会将对象(以及模块的所有函数、类、变量等)的所有特性列出
dir(sys) -> 列表[‘a’, ‘b’, …]
from copy import *
copy.__all__ 过滤
如果没有设定__all__ 用import *语句默认导出所有不以下划线开头的全局名称。
help(copy.copy) copy模块中的copy函数
print copy.copy.__doc__

模块的源代码
print copy.__file__

标准库
-sys
argv
exit([arg])
modules
path
platform
stdin
stdout
stderr
-os
environ
system(command)
sep
pathsep
linesep
urandom(n)

webbrowser模块

-fileinput
input
filename()
lineno()
filelineno()
isfirstline()
isstdin()
nextfile()
close()
-collections
-heapq #堆
-time
-random
-shelve #序列化 保存到文件
-re #正则表达式

open 默认读模式
+ 参数可以用到其他任何模式中,指明读和写都是允许的。比如r+能在打开一个文件用来读写时使用。
r 读模式
w 写模式
a 追加模式
b 二进制模式 (可添加到其他模式中使用)
rb 读取二进制文件

f = open(r’c:\file.txt’, ‘w’)
f.write(‘0112345’)
f.seek(5)
f.close()
f.read()

file.readline() 读取一行 (包含换行符)
file.readlines()

# Open your file here
try:
# Write data to your file
finally:
file.close()

# Python2.5 from __future__ import with_statement
# 自动close
with open(“somefile.txt”) as somefile:

with 上下文管理 __enter__ __exit__ contextlib模块
do_something(somefile)

当到达文件末尾时,read方法返回一个空的字符串。

数据库
Python DB API的模块特性
apilevel 所使用的Python DB API版本
threadsafety 模块的线程安全等级
paramstyle 在SQL查询中使用的参数风格

socket模块

urllib urllib2模块
能让通过网络访问文件,就像那些文件存在于你的电脑上一样。通过一个简单的函数调用,几乎可以把任何URL所指向的东西用作程序的输入。

如果需要使用HTTP验证或cookie或者要为自己的协议写扩展程序的话,urllib2是个好的选择。

标准库中一些与网络相关的模块

服务器框架
SocketServer
BaseHTTPServer
SimpleHTTPServer
CGIHTTPServer
SimpleXMLRPCServer
DocXMLRPCServer

基于SocketServer的服务器

Twisted 一个非常强大的异步网络编程框架

文件是一个可迭代对象

使用默认浏览器打开某个网址
import webbrowser
webbrowser.open(‘www.baidu.com’)

集合 set
set([0, 1, 2, 3])
set会剔除重复元素
set的元素顺序是随意的
a = set([1, 2, 3])
b = set([2, 3, 4])
并集 a.union(b) a | b
交集 a.intersection(b) b & b
a.issuperset(b)
a.issubset()
a.difference(b) a – b
a.symmetric_difference(b) a ^ b
a.copy()

reduce(func, [a, b, c])
reduce执行以下步骤
tmp = func(a, b)
tmp = func(tmp, c)

time 模块
time() 当前时间 – 1970至今的秒数
localtime() 将秒数转换为日期元组,本地时间
asctime() 将日期元组转换为字符串
mktime() 将日期元组转换为本地时间(秒数) 与localtime()功能相反
sleep()

datetime 模块
支持日期和时间的算法

timeit 模块
帮助开发人员对代码段的执行时间进行计时

random 模块
random() 0<= n < 1
randrange([start], stop, [step]) [start, stop) 随机整数
uniform(a, b) [a, b] 随机实数
choice() 从给定序列中选择随机元素
shuffle() 将给定(可变)序列的元素进行随机移位
sample() 从给定序列中 选择给定数目的元素,同时确保元素互不相同

re 正则表达式模块
compile(pattern, [flags]) 根据包含正则表达式的字符串创建模式对象
search(pattern, string, [flags]) 在字符串中寻找模式,返回第一个匹配的MatchObject
match(pattern, string, [flags]) 在字符串的开始处匹配模式,返回MatchObject
split(pattern, string, [maxsplit=0]) 根据模式的匹配项来分割字符串,返回列表
findall(pattern, string) 列出字符串中模式的所有匹配项,返回列表
sub(pat, repl, string, [count=0])将字符串中所有pat匹配项用repl替换
escape(string) 将字符串中所有特殊正则表达式字符转义

pattern =
re.sub(pattern, r'<em>\1</em>’, ‘Hello, *world*!’)
\1 引用模式匹配中的组

模式匹配默认是贪婪模式
所有的重复运算符都可以通过在其后面加上一个问号变成非贪婪版本

string模块中的模板系统 template类

functools 通过部分参数来使用某个函数,稍后再为剩下的参数提供数值
difflib 这个库让你可以计算两个序列的相似程度,
还能让你在一些序列中找出和提供的原始序列最像的那个。
可以用于创建简单的搜索程序
hashlib 如果为两个不同的字符串计算出了签名。几乎可以确保这两个签名完全不同。
加密和安全性 见 md5 sha 模块
csv 读写csv文件
timeit profile trace
itertools
logging
getopt optparse
cmd

项目3 万能的XML
from xml.sax.handler import ContentHandler
from xml.sax import parse

class MyHandler(ContentHandler):
parse(‘website.xml’, MyHandler)

str.capitalize()
getattr()
callable()
os.makedirs(‘foo/bar/baz’)
os.path.isdir()
a = [‘hello’]
*a + [‘boys’] -> * (a + [‘boys’])

项目4 新闻聚合
nntplib
NNTP(Network News Transfer Protocal,网络新闻组传输协议)
urllib
strftime(‘%y%m%d’) # 年月日
strftime(‘%H%M%S’) # 时分秒

body = server.body(id)[3] # 返回一个字符串列表
打印完所有文章后 调用server.quit()

list.extend(list)
list.append(object)

BBC新闻网页的HTML页面布局可能会变,如果这样的话就需要重写正则表达式。
在使用其他页面的时候也要注意这样的情况。要查看HTML源代码然后试着去找到适用的匹配模式。

file
str
unicode
zlib
gzip
bz2
zipfile
tarfile
shutil

《C++ GUI Qt 4 编程》 笔记(七)

第21章 创建插件

动态链接库
LIBS += -ldb_cxx
INCLUDEPATH += /usr/local/BerkeleyDb.4.2/include

QLibrary 动态加载dll

插件
常见的插件类型:
数据库驱动程序、图像格式、风格、文本编码解码器

实现一个插件
需要实现两种类:
插件类 提供访问插件功能(处理器类)的接口
处理器基类 插件提供的功能

.pro
TEMPLATE = lib
CONFIG += plugin // 指明是插件库而不是通用库

Qt应用程序在plugins目录中寻找插件比如 plugins/styles
如果需要将Qt插件配置到其他目录中
需要在代码中扩展搜索路径
QCoreApplication::addLibraryPath()
或设置QT_PLUGIN_PATH环境变量

自定义插件
1.定义接口

2. 定义插件

感知插件,加载插件

第22章 应用程序脚本

QtScript模块 ECMAScript (JavaScript标准)

1.把脚本读入QString
2.创建一个QScriptEngine对象,并设置应用程序相关的功能
3.执行脚本

QFileSystemWatcher

脚本:
pi.js
return 3.14;
cube.js
return x * x * x;

QSyntaxHighlighter

QUiLoader

扩展QVariant处理的类型
Q_DECLARE_METATYPE(QScriptValue)

第23章 平台相关特性

平台相关的编程接口
Windows Win32
Mac OS X Carbon
X11 Xlib

QWidget::winId() 返回平台相关的窗口句柄

QWidget::find() 返回指定窗口ID对应的QWidget

平台相关宏定义
Q_WS_MAC
Q_WS_X11
Q_WS_WIN
Q_WS_QWS (Qtopia)

系统版本
QSysInfo::WindowsVersion()
QSysInfo::MacintoshVersion()

编译器宏
Q_CC_MSVC

Qt/Windows桌面版 提供了ActiveQt框架,用以为ActiveX和Qt提供完美结合。
ActiveQt由两个模块组成:
QAxContainer 允许我们使用COM对象并且可以在Qt应用程序中嵌入ActiveX控件
QAxServer 允许我们导出使用Qt编写的自定义的COM对象和ActiveX控件

.pro
CONFIG += qaxcontainer
CONFIG += qaxserver

Q_ENUMS()宏
用来告诉moc在槽中使用的该类型为一个枚举类型

QAxObject封装一个COM对象
QAxWidget封装一个ActiveX控件
QAxBase为QAxObject和QAxWidget实现了COM的核心功能

编写服务器

当包括一个源于QObject类的多重继承的时候,必须总是把这个起源于QObject的类放在第一位,以便moc可以快速识别它。

Q_PROPERTY()宏 使用该宏声明的属性可以用setProperty()设置值

第24章 嵌入式编程

Qt/Embedded Linux (Qtopia Core)是为嵌入式Linux优化过的Qt版本

《C++ GUI Qt 4 编程》 笔记(六)

第17章 提供在线帮助

工具提示

状态提示 显示在状态栏上

What’s This? 文本帮助

当处于what’s this模式下时(windows 标题栏问号按钮 或shift + f1)
单击窗体,将显示设置的帮助文本

QWhatsThis::createAction();

当用户按下F1键或单击Help菜单项时,应用程序主窗口会调用help()槽

QTextBrowser

QWidget::setAttribute(Qt::WA_DeleteOnClose)
// 通常模式对话框不允许和这个应用程序中的其他任何窗口进行交互
// 以下代码允许这种交互
QWidget::setAttribute(Qt::WA_GroupLeader)

textBrowser->documentTitle();

Qt Assitant库
.pro
CONFIG += assistant

第三部分 Qt高级

第19章 Unicode

QTextCodec::codecForLocale() 获得本地字符集

让应用程序感知翻译
1. tr()
2. 程序启动时,载入一个翻译文件.qm

另一种方式:

lupdate工具

不要含有变量

应该这样

QT_TRANSLATE_NOOP(“上下文”, “xxx”);

禁止const char* 到QString的隐含转换
在包含任意Qt头文件之前预先定义:
QT_NO_CAST_FROM_ASCII
或在.pro中
DEFINES += QT_NO_CAST_FROM_ASCII

QLocale 提供本地化的数字和日期以及时间格式

动态改变语言
只需重新加载翻译文件,然后重新设置需要翻译的文本

翻译应用程序:
1. 运行lupdate,从应用程序的源代码中提取所有用户可见的字符串
2. 使用Qt Linguist翻译应用程序
3. 运行lrelease,生成二进制的.qm文件,应用程序可以使用QTranslator加载这个文件

在.pro中加入需要支持的语言
当第一次运行lupdate时会创建这两个文件xml格式
ts – translate source
qm – Qt Message
TRANSLATIONS = spreadsheet_de.ts spreadSheet_fr.ts

lupdate -verbose spreadsheet.pro

CODECFORTR = …
QTextCodec::setCodecForTr()

lrelease -verbose spreadsheet.pro

第19章 自定义外观

三种方法重新定义Qt内置窗口部件的外观
1. 子类化窗口部件类
2. 子类化QStyle或者一个预定义的风格比如QWindowStyle,Qt通过这种方法为不同平台提供基于平台的外观
3. Qt样式表 受CSS启发

样式表作用于上层的当前激活的QStyle上,因为创建样式表不引入任何子类,所以它们适合对现有窗口部件做微小的定制。

例如:
想在应用程序中的所有QLineEdit中使用黄色作为背景色

QObject::setProperty()

QStyle
内置样式类:
QStyle
|- QCommonStyle
|  |-QWindowStyle
|  |-QCleanlookStyle
|  |-QMacStyle
|  |-QPlastiqueStyle
|  |-QWindowsXPStyle
|  |-QWindowsVistaStyle
|
|- QMotifStyle
|- QCDEStyle

class MyPushButton : public QWidget

QApplication::setStyle() // 设置整个应用程序的样式
QWidget::setStyle() // 为个别窗口部件设置样式

drawControl()函数被各种QStyle的子类重新实现,用于绘制窗口部件
第20章 三维绘图 OpenGL

1. 子类化QGLWidget
2. 实现几个虚函数
3. 连接QtOpenGL OpenGL库

.pro
QT += opengl

OpenGL QPainter结合
在paintEvent()函数绘制
1. 创建一个QPainter
2. 使用QPainter绘制背景
3. 保存OpenGL状态
4. 使用OpenGL操作绘制场景
5. 恢复OpenGL状态
6. 使用QPainter绘制前景
7. 销毁QPainter

QGLWidget::renderText()

使用帧缓存对象生成叠加
基本思路:
1. opengl渲染到纹理
2. 将纹理绘制到窗口
3. 将选择框绘制到窗口
假如只有窗口大小改变时才重新opengl渲染
这时,假如选择框的大小改变,而窗口大小没有改变时,则只需要绘制一张纹理和一个选择框,模型并不需要频繁渲染。

《C++ GUI Qt 4 编程》 笔记(五)

第15章 网络

QFtp
QHttp

QTcpSocket QSslSocket
QUdpSocket

使用QCoreApplication而不是QApplication以避免连接到QtGui库

QUrl类提供了一个高级接口,用来提取URL的不同部分,如文件名称、路径、协议和端口

当所有请求都已处理完时,QFtp就发射done(bool)信号,bool表明是否有错误发生

FTP指令在Qt的事件循环中排队并等待执行。

QFtp提供的FTP指令函数
connectToHost()
login() close() list() cd() get() put() remove()
mkdir() rmdir() rename()

使用rawCommand() 可以执行任意FTP指令
ftp.rawCommand(“SITE CHMOD 755 fortune”)

QFtp信号
commandStarted(int) // int 指令ID号
commandFinished(int, bool)
stateChanged() // 只要连接进入了一个新状态就会发射该信号
done(bool) // 一旦指令队列变空,就会发射这个信号
listInfo(const QUrlInfo&) // 对list()处理的每一个文件调用该信号
如果发生错误,QFtp会自动清空指令队列,错误指令后面的指令将不会执行

.pro
QT += network

QUrlInfo urlInfo;
urlInfo.isSymLink()

QHttp
get() post() 是异步工作的,调用时立即返回,当控制权回到Qt事件循环时才会开始传输数据

QHttp貌似在Qt5中已经不存在了

QTcpSocket

连接成功后会发送connected()信号
连接失败会发送error(QAbstracSocket::SocketError)信号
readyRead()信号 只要QTcpSocket已经从服务器收到新数据,就会发射该信号

QTcpServer 信号
incomingConnection(int socketId)

QTcpServer
.listen(QHostAddress::Any, 6178); // any 表示 本地主机上的任意IP地址 0.0.0.0

基于行

发送数据使用QTextStream

QHostInfo::fromName()
QHostInfo::lookupHost()

UTP客户端

第16章 XML

QtXml模块的三个不同编程接口
QXmlStreamReader 一个用于读取格式良好的XML文档的快速解析器
DOM 将XML文档转换为应用程序可以遍历的树形结构
SAX 通过虚拟函数直接向应用程序报告解析事件

XML文件写入,三种方法:
1. 使用QXmlStreamWriter
2. 在内存中以DOM树的结构表示数据,并要求树结构将自己写到文件中
3. 手动生成XML

QXmlStreamReader
.readNext()
.isStartElement()
.isCharacters()

.pro
QT += xml

Qt的SAX类时对基于SAX2的java实现的模拟

QXmlSimpleReader
QXmlContentHandler
QXmlErrorHandler

继承自QXmlDefaultHandler
重写事件处理函数
startDocument()
startElement()
characters()
endElement()
endDocument()
fatalError()

XML保存

QXmlStreamWriter自动处理转义字符

《C++ GUI Qt 4 编程》 笔记(四)

第12章 输入与输出

QIODevice 基类

QFile
QTemporaryFile 临时文件
QBuffer 从QByteArray中读取或写入数据
QProcess 运行外部程序并处理进程间通信
QTcpSocket
QUdpSocket
QSslSocket 利用SSL/TLS在网络上传输加密数据流
后4个为顺序存储设备
前3个为随机存储设备 seek()

QDataStream 读写二进制数据
QTextStream 读写文本数据
这2个类考虑了字节顺序和文本编码等问题
比标准c++更加方便,标准c++将这些问题留给了程序员来处理。

QFile QDir QFileInfo

通过QFile打开文件
然后通过QDataStream对象存取

qRegisterMetaTypeStreamOperators<T>()

QIODevice

压缩解压缩
qCompress()
qUncompress()
QtIOCompressor()

QTextStream
处理了字符集编码转换、不同的行尾符的转换
还支持C++基本数字类型,处理数字与字符串之间的转换

stream.setCodec(“UTF-8”);

可以应用在QString上
QString str;
QTextStream(&str);

QDir 提供与平台无关的遍历目录并获得有关文件信息的方法

QDir::convertSeparators() 将斜线转为针对具体平台的正确的分隔符

QDir::currentPath();
QDir::homePath();
QCoreApplication app(argc, argv);
QStringList args = QCoreApplication::arguments();

dir.entryInfoList();
dir.rename();
dir.exists();
dir.mkdir();
dir.rmdir();

QFile::remove();
QFile::exists();

QFileSystemWatcher可以通过发送directoryChanged()、fileChanged()信号,在目录或者文件发生任何改变时通知我们。

QFile可以使用嵌入资源 e.g. :/datafiles/file.dat

进程间通信
QProcess允许我们执行外部程序并且和它们进行交互,这个类时异步工作的,且它在后台完成的工作。当外部进程得到数据或者已经完成时,QProcess会发出信号通知我们。

QDir::toNativeSeparators(fileName);

QProcess信号
readyReadStandardError()
finished()
error()

QTemporaryFile临时文件

QProcss::execute()静态函数运行外部程序并等待外部进程完成。

process.waitForStarted()
process.waitForFinished()

Windows下的ActiveQt扩展程序

如果想启动用户喜欢的网页浏览器或电子邮件客户端程序,只需要:
QDesktopServices::openUrl()

第13章 数据库

1. QSqlQuery 提供了一种直接执行任意SQL语句并处理其结果的方式
2. QSqlTableModel QSqlRelationalTableModel

数据库驱动
QMYSQL
QOCI 甲骨文公司
QODBC
QSQLITE SQLite3
QSQLITE2

query.numRowsAffected()

Oracle风格语法

ODBC风格语法

高级界面接口 QSqlTableModel

.pro文件
QT += sql

QDataWidgetMapper
第14章 多线程

子类化QThread并且重新实现run()函数

QThread成员函数
terminate() 终止线程执行
isRunning()
wait()

线程同步

QMutex 每次只能有一个线程可以访问同一个变量
QReadWriteLock 允许执行多个读取访问而不会影响性能
QSemaphore 用于保护(guard)一定数量的相同资源
QWaitCondition 允许一个线程在满足一定的条件下触发其他多个线程

QMutexLocker 构造函数锁定,析构函数解锁
QMutexLocker locker(&mutex);

QReadLocker
QWriteLocker

semaphore信号量的一个典型应用场景是:
当两个线程间传递一定量的数据时,这两个线程会使用某一特定大小的共享唤醒缓冲器。

线程局部存储
QThreadStorage<T>
.hasLocalData()
.setLocalData()
.localData()

与主线程通信
主线程是唯一允许创建QApplication或QCoreApplication对象,并且可以对创建的对象调用exec()的线程。

以上同步技术没有一个可以用来与主线程进行通信,因为它们会锁住事件循环并且会冻结用户界面。

使用信号和槽与主线程通信
例如:
在一个图像处理软件中,图像保存在线程对象中,在界面上选择对图像应用的变换时,主线程将包含该事务的事务对象添加到线程对象的事务列表中,线程对象后台对图像进行变换,当变换完成后通知主线程

如果需要删除一个存在于不同线程中的QObject对象,则必须调用线程安全的QObject::deleteLater()函数,它可以置入一个延期删除事件。

事件循环
QThread::exec()
QProcess::waitForFinished()
QAbstractSocket::waitForDisconnected()

可重入类:
类的多个实例可以安全地在多个线程中访问。
QWidget和它的子类都是不可重入的,这样造成的后果之一就是我们不能在一个来自次线程的窗口部件上直接调用函数。
可以通过发送信号或者: