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

8 篇文章 0 订阅

第15章 网络

QFtp
QHttp

QTcpSocket QSslSocket
QUdpSocket

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

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

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

connect(&ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool)));

bool Ftp::getFile(const QUrl& url)
{
	if (!url.isValid())
		return false;

	if (url.scheme() != "ftp")
		return false;

	if (url.path().isEmpty())
		return false;

	QString localFileName = QFileInfo(url.path()).fileName();
	if (localFileName.isEmpty())
		localFileName = "ftpget.out";

	file.setFileName(localFileName);
	if (!file.open(QIODevice::WriteOnly))
		return false;

	ftp.connectToHost(url.host(), url.port(21));
	ftp.login(); // 匿名登录
	ftp.get(url.path, &file); // 如果要保存到内存中 QBuffer
	ftp.close();
	return true;
}

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

void FtpGet::ftpDone(bool error)
{
	// ...
	file.close();
	emit done(); // done()调用app.quit()
}

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()

QBuffer* buffer = new QBuffer;
buffer->open(QIODevice::WriteOnly);
ftp.get(urlInfo.name(), buffer);

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

connect(&http, SIGNAL(done(bool)), this, SLOT(httpDone(bool)));
http.setHost(url.host(), url.port(80));
http.get(url.path(), &file);
http.close();

http.setHost("www.example.com");
http.post("/cgi/somescript.py", "x=200&y=320", &file);

QHttpRequestHeader header("POST", "/search.html");
header.setValue("Host", "www.trolltech.com");
header.setContentType("application/x-www-form-urlencoded");
http.setHost("www.trolltech.com");
http.request(header, "qt-interest=on&search=opengl");

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

QTcpSocket

// 连接函数会立即返回
tcpSocket.connectToHost("tripserver.zugbahn.de", 6178);
progressBar->show();

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

QByteArray block;
tcpSocket.write(block); // 基于块

QTcpServer 信号
incomingConnection(int socketId)

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

基于行

QStringList lines;
while (tcpSocket.canReadLine())
	lines.append(tcpSocket.readLine());

发送数据使用QTextStream

QTimer timer;
timer.start(2 * 1000);
connect(&timer, SIGNAL(timeout()), this, SLOT(sendDatagram()));
QByteArray datagram;
QDataStream out(&datagram, QIODevice::WriteOnly);
	out << ... ;
// 不接受主机名称,只接受主机地址
udpSocket.writeDatagram(datagram, QHostAddress::LockHost, 5824);

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

UTP客户端

udpSocket.bind(5824);
connect(&udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));

QByteArray datagram;
datagram.resize(udpSocket.pendingDatagramSize());
udpSocket.readDatagram(datagram.data(), datagram.size());

第16章 XML

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

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

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

QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text))
	return false;
QXmlStreamReader reader;
reader.setDevice(&file);
reader.readNext();
while (!reader.atEnd())
{
	if (reader.isStartElement())
	{
		if (reader.name() == "bookindex")
			readBookindexElement();
		else
			// 将导致下一次调用atEnd()返回true
			// QFile::error() QFile::errorString()获得错误信息
			reader.raiseError(QObject::tr("Not a bookindex file"));
	}
	else
		reader.readNext();
}

file.close();
if (reader.hasError())
	// reader.errorString()
	return false;
else if (file.error() != QFile::NoError)
	// file.error.String()
	return false;

.pro
QT += xml

QDomDocument doc;
doc.setContent(&file, ...);
QDomElement root = doc.documentElement();
root.tagName();

QDomNode child = element.firstChild();
while (!child.isNull)
{
	child.toElement().tagName();
	child = child.nextSibling();
}

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

QXmlSimpleReader
QXmlContentHandler
QXmlErrorHandler
...

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

QFile file(fileName);
QXmlInputSource inputSource(&file);
QXmlSimpleReader reader;
reader.setContentHandler(this);
reader.setErrorHandler(this);
reader.parse(inputSource);

XML保存

QXmlStreamWriter自动处理转义字符

QXmlStreamWriter xmlWriter(&file);
xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement(...);
xmlWriter.writeAttribute();
...
xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();

QDomDocument doc;
doc.save();

// QTextStream::setCodec()
doc.save(..., QDomNode::EncodingFromTextStream);

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值