近期Qt编程的一些总结

http://blog.sina.com.cn/s/blog_4a33cfca01019uol.html


最近做了一些网络方面的程序,包括Android和PC上的,当然基本上都是在周末或者业余时候写的。这里总结一下,以免遗忘。

 

Android上面如果要抓去网络数据包,那么可以使用libpcap,毕竟Android底层还是一个Linux。编译libpcap包需要在NDK的环境下进行。但是直接下载libpcap包还不能够编译,如果水平够高,可以在源码上修改;但是更方便的是直接从Android官网上下载:$git clone git://android.git.kernel.org/platform/external/libpcap.git。然后以一般的NDK程序去编译就好了。

 

NDK编译的话,安装好后,把程序可以都放在samples里面,这样方便,然后命令行里面敲入:ndk-build.cmd NDK_PROJECT_PATH=项目的地址,即可。具体可以参看NDK的编程手册。

 

Qt里面跟网络相关的主要是QtNetwork和QtWebKit这两个模块。前者包括TCP、UDP等等协议的支持以及HTTP协议的支持;后者则是强有力的浏览器内核WebKit的Qt上的实现。

 

QtNetwork中,QNetworkAccessManager负责维护网络连接的状态,一般一个程序内只要有一个QNetworkAccessManager就够了。给一个URL链接,可以通过下面的方式用GET的形式发送出去:QNetworkReply *reply = nam->get (QUrl (urlstring)); nam就是一个QNetworkAccessManager对象。返回的reply可以用于nam在接收到数据后的响应。需要注意的是,Qt中Network模块的响应都是异步的。Qt很好的用了它的信号与槽机制来实现了这种异步。一般我们将QNetworkAccessManager的finished (QNetworkReply * reply)信号跟某一个槽函数链接,然后根据入口参数来判断到底是之前哪个get的返回值,从而允许分别作处理。这种方式个人感觉非常之优雅。

 

get获得数据后,可以用一个QWebPage将其梳理,即新建一个QWebPage,然后让它的mainFrame()->setHtml (QString(reply->readAll()))。具体要查找html里面的某个节点,可以完全参照CSS里面的索引语法来制定。具体参看http://www.w3.org/TR/CSS2/selector.html#q1。其实说白了,一个html页面就是一个xml文件,很多查找、编辑操作跟xml操作类似。

 

Qt可以操作多种数据库,并提供了统一的借口。这些数据库的驱动都在plugins/sqldrivers里面。需要注意的是,在发布Qt应用程序时,需要连带驱动一起发布,否则驱动无法工作了。具体作法是:发布的程序所在的目录建立sqldrivers文件夹,然后将具体用到的驱动的dll文件从plugins/sqldrivers里面拷贝到该文件夹中(注意,发布时,sqldrivers文件夹和程序处于同一目录,不再有plugins文件夹!)。

 

Qt操作Excel时有两种方式,一种是把Excel看作一种ODBC驱动的数据库,因此可以调用微软的ODBC接口进行读取;另一种是利用Qt的AxtiveX机制,用QAxObject来操作Excel。前者的优点是速度非常快,但是缺点也很明显,那就是可控制能力弱,而且就我目前了解到的情况来看该方法只能读取excel而无法导出excel。QAxObject的方法优点是可控制能力非常强,理论上可以实现Office Excel界面中所有的功能(实际上它就相当于在你自己的程序中嵌入了一个Excel控件),不单单能够读取、导出数据,还能够控制字体颜色、列宽等等,缺点是运行非常慢!尤其是第一次运行,有时候简直无法容忍!第一种的示例代码如下:
QString dsn = QString("DRIVER={Microsoft Excel Driver (*.xls)};DBQ=%1").arg(filePath);
db.setDatabaseName(dsn);
db.open();
这样就可以把一个Excel文件当作数据库打开了。之后就是一般的数据库查询语句,没啥区别。需要注意的是,微软的ODBC在连接Excel时有一个bug,那就是不管你在dsn上有无设置FIRSTROWHASNAMES,微软的ODBC都默认把Excel的第一行当作名字行,也就是相当于数据库中表的column name。所以用这种方法的话,切忌Excel文件的第一行不能放实际的数据。第二种方法的示例代码如下:
excel = new QAxObject("Excel.Application");
if (!excel)
{
 QMessageBox::critical(NULL, tr("错误信息"), tr("EXCEL对象丢失"));
 return;
}
excel->dynamicCall("SetVisible(bool)", false);
workbooks = excel->querySubObject("WorkBooks");
workbook = workbooks->querySubObject("Open(QString, QVariant)", m_filePath);
worksheet = workbook->querySubObject("WorkSheets(int)", 1);//打开第一个sheet
usedrange = worksheet->querySubObject("UsedRange");//获取该sheet的使用范围对象
rows = usedrange->querySubObject("Rows");
columns = usedrange->querySubObject("Columns");

 

用Qt SQL语句判断数据库中有无某一记录时,只需要先SELECT查询,然后判断query.next ()返回值即可;为true则表明数据库中有该记录,否则表示没有。

 

Socket通信时,PC连接模拟器用localhost即127.0.0.1,模拟器连接pc用10.0.2.2。有时候虚拟机网络会不稳定,也不知道为什么;问了度娘和谷哥,有说是因为模拟器的dns问题,但是我改了,效果也不是很明显。

 

最后总结一句:Qt实在太好用了!

你可能感兴趣的:(qt)