qt windows下 如何 运行msbbslupdate.exe命令

温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
以下包括了部分网上收集的,以及qt帮助里的内容(Deploying an Application on Qt/Windows)
环境是QT 4.3.3 + mingw32-make
部署发布QT程序有两种方法:
第一种,静态编译,可生成单一的可执行文件。
第二种,动态编译,需同时附上需要的dll文件。
一、静态编译
1 编译QT。
要静态编译,首先要求QT是静态编译过的。在QT目录下执行:
configure.exe -static -release
make sub-src
就可以编译出静态库。如果只是用来分发程序,也可以mingw32-make release sub-src只编译一个静态库。
这个过程需要1-2个小时。QT目录会变成1.8G左右。注:mingw32-make和make是一样的。
如果用VC2005平台,在编译Qt的时候,configure.exe -static -platform win32-msvc2005
然后nmake sub-src或者nmake release sub-src完成静态编译。
2 编译程序。
然后到你自己的程序目录下执行:
make clean
qmake -config release
这时会得到一个非常大的可执行程序,但也会有一个重要的问题,就是图片文件显示不出来。
按照QT帮助的说法,QT里的jpeg,gif等图片的支持都是以插件的形式存在的,现在我们还没有包含任何插件。
3 加入插件
在main.cpp里:
#include &QApplication&
#include &QtPlugin& //这个
Q_IMPORT_PLUGIN(qjpeg) //这个
Q_IMPORT_PLUGIN(qgif) //这个
int main(int argc, char *argv[])
QApplication app(argc, argv);
return app.exec();
在.pro里加入:
QTPLUGIN += qjpeg qgif
CONFIG += static
QT的帮助里就做到这里,但我编译程序时出错如下:
release/main.o(.text+0x1c9):main.cpp:
undefined reference to `qt_plugin_instance_qgif()'
undefined reference to `qt_plugin_instance_qjpeg()'
经过长时间研究,发现了解决问题的办法:
4 加入LIBS
在.pro中加入:
LIBS += C:/Qt/4.3.3/plugins/imageformats/libqgif.a
LIBS += C:/Qt/4.3.3/plugins/imageformats/libqjpeg.a
如果QT静态编译正确的话,你应该上面这个目录下看到这两个文件libqgif.a和libqjpeg.a (据说以前的QT版本也可能是.lib或.o文件)
这时已经可以正常编译运行了。但还是需要mingwm10.dll才能运行。
5 解决MinGW的mingwm10.dll依赖问题
在Makefile.release里找到:
LFLAGS = -enable-stdcall-fixup
-Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -static -Wl,-s
-Wl -mthreads -Wl, -subsystem,windows
删除其中的"-mthreads"
一般只有用到threads的时候才用到mingwm10.dll,我们通常遇到的"缺少mingwm10.dll"问题,可以在程序qmake生成
makefile.release文件后删除"-mthreads"参数即可,一般在
"LFLAGS"后面。当然,这只是临时解决方案,每次都要手动修改,也可以在编译QT前先修改qmake.h,不过不推荐这种方法。其实,
mingwm10.dll也就十多K,每次发布程序时一起打包也无所谓。
更多信息可以参考:
/qt-interest/2006-08/thread00942-0.html
/qt-interest/2005-10/thread00381-0.html#msg00553
这时编译同样得到一个非常大的可执行程序(我写的这个贪吃蛇一共500多行,生成的exe有8M)。用AspPack压缩一下。就可以发给用户了(这时是2.6M)。
quote: "这样编译出来的程序比较大,可以先用strip命令去掉程序里面一些无用信息后,用ASPack或者UPX之类的压缩加壳软件压缩一下,两者的压缩率基本都达到30%多一点,压缩效果还是很明显的。"
二、动态编译
动态编译就很容易了。用QT的默认安装,把生成的release下的exe文件,和下面几个核心文件放在一个文件夹里:
MINGWM10.DLL
QTGUI4.DLL
QTCORE4.DLL
VC2005编译程序运行时需要的几个dll文件
Microsoft.VC80.CRT.manifest 位于x:\Program Files\Microsoft Visual Studio 8\VC\redist\x86\\Microsoft.VC80.CRT
msvcm80.dll
msvcp80.dll
msvcr80.dll
QtCore4.dll
QtGui4.dll
这样就可以运行了。但图片文件还是可能显示不出来,解决办法:
把程序文件夹里,建立一个imageformats目录(必须是这个名字),把qt目录下的plugin/imageformats目录下对应的dll文件copy过去。这样动态连接就完成了。
注:可以用微软的Dependency Walker tool工具,就是一个depends.exe的程序,来查看一个exe文件跟哪些dll关联。
注:需要在完全没有装QT的系统上测试发布的程序有没有DLL依赖问题。(转帖)QT4.3.3+VC6.0安装编译教程
我是从QT中文论坛转来的
QT4.3.3+VC6.0安装编译过程详解
A.& & 安装前的准备
检查你的QT4.3.3压缩包的位置,并解压。假设解压后的路径为F:\qt433,那么需要先设置环境变量,首先在“我的电脑”—“属性”---“高级
”---环境变量---**的用户变量-- -新建,添加一个变量名为QTDIR
变量值为F:\qt433(注意:要对应qt解压后的路径),然后继续添加环境变量,变量名为QMAKESPEC,变量值为win32-msvc,在
PATH变量中也应加入F:\qt433\bin.为安装好的qmake所在路径,使得命令行里面可以用qmake。
然后检查vc6.0是否安装好,假设安装后路径为F:\Program Files\Microsoft Visual Studio\……注意:安装时应选择
打开vc6.0检查一下: tools---options---directories,如果正常应该可以看到一下结果:
在目录(directories)里边应该自动添加了这么目录信息,并借检查环境变量里边也已经有了相应的环境变量。
B.& & 现在进行检查 并安装
打开命令提示符:cmd界面
输入 nmake,检查vc是否安装好
然后是转到f盘下进入qt433目录执行
congfigure –debug-and-release,(这个作用是编译出 debug版本和release版本的qt的库,更多选项 可以用configure –help)
Configure完了后输入nmake&&开始编译qt,视机器情况大约安装两个小时左右。
成功之后会有如下提示
Please enjoy !
C.& & 下面进行编译
我们就拿qt中文网上的一个高手的作品为例 作品为图片浏览器&&我们把他做好的压缩包压缩到一个路径下 (注意:路径名最好不要有中文) 假设我们解压到F:\jjk\456下
里边已经有了pro文件。
两种编译方法:
第一种:纯命令式
在命令窗口中,转到F:\jjk\456路径下
先qmake(qmake会找 里面的pro文件 就是qt的工程文件)
我们看到qmake之后生成了debug和release目录和makefile、makefile.debug 和makefile.release文件
图中选中的为qmake之后生成的文件
然后是nmake
我们可以看到 在debug目录下已经有了很多文件 其中就有可执行文件qtimage.exe 就可以执行了
这就是执行的结果。
另外一种方法:在vc中编译
首先要用命令行根据pro文件生成vc的工程文件 dsp
F:〉jjk\456\ qmake&&–t&&vcapp
File----open ---从文件类型中选择projects(.dsp)
然后到那个路径下选中 QtImage.dsp 打开 build—rebuild all—build---execute qtimage.exe
THAT’S ALL!!!我在按照上述教程编译安装的时候,输入nmake进行编译的时候出现了如qtfh1错误提示,我在网上也看到了有不少人有同样或类似的情形,不过就是没有
解决方案。我也想了很多办法,试了很多办法,都以失败告终。最后一气之下将vc卸了重装居然就通过了,具体原因我不清楚,可能由于我的vc是以前安装的缘
故。如果有遇到同类问题,不妨将vc卸了重装试试。
编译成功后,可以用一个简单的QT程序进行测试,新建一个名为hello的文件夹,并新建一个hello.cpp的文件,输入代码
#include &QtGui/QApplication&
#include &QtGui/QWidget&
#include &QtGui/QLabel&
#include &QtCore/QTextCodec&
#include &QtGui/QPushButton&
#include &QtGui/QVBoxLayout&
int main(int argc, char* argv[])
& && &&&QApplication app(argc, argv);
& && &&&QTextCodec::setCodecForTr(QTextCodec::codecForName("gb18030"));
& && &&&QWidget* pWidget = new QW
& && &&&QLabel label(pWidget);
& && &&&label.setText(QObject::tr("同一个世界,同一个梦想!"));
& && &&&QPushButton* btn = new QPushButton(QObject::tr("关闭"), pWidget);
& && &&&QVBoxLayout* layout = new QVBoxL
& && &&&layout-&addWidget(&label);
& && &&&layout-&addWidget(btn);
& && &&&pWidget-&setLayout(layout);
& && &&&QObject::connect(btn, SIGNAL(clicked()), pWidget, SLOT(close()));
& && &&&pWidget-&show();
& && &&&return app.exec();
然后在命令行下进行编译,并执行。2) 建立Qt工程
“File” -& "New" -& "New Project"
在Qt目录下面选择“Qt Gui Project”,
"Next", 然后输入工程名字,剩下的只需要一路取默认值即可。
3) 在窗体上添加按钮
双击工程里面的ui文件,打开窗体编辑窗口.
在菜单"Window" -& "Show View" -&
"Other..."
选择"Qt C++ Widget Box",点击"OK",就可以打开控件窗口了,如下图:
以同样方式打开"Qt C++ Signal Slot Editor"窗口.
4) 在窗口上放置两个按钮,在按钮上右键修改objectName和text.
两个的objectName分别是:"Button1","Button2:".
text分别是:"Show Box", "Close"
5) 添加按钮事件
在"Qt C++ Signal Slot Editor"窗口里面,单击"+"图标,这时候再窗口里面出现一行内容.
将双击"",选择“Button2”;双击“”,选择"clicked()";双击"",选择"close()".
打开主窗口类头文件(我的是qqq.h), 添加信号响应部分和函数:
private slots:
&&& void on_Button1_clicked();
这个函数的格式必须是:on_控件名_事件类型()
在cpp文件里面,添加头文件及函数实体:
void qqq::on_Button1_clicked()
&&& QMessageBox box(this);
&&& box.setText("Hello World!");
&&& box.exec();
6) 在Eclipse里面,编译运行程序即可。
效果如下:
1.默认的Qt for MinGW的安装,是不安装调试库的,如需运行Debug模式,按照下面的方法编译调试库,
在Qt的bin目录里面,用命令:
qtvars.bat compile_debug
来编译调试库。
需要大约3G的磁盘空间,大约4个小时的编译时间。
2.如果安装完qt-eclipse-integration-win32-1.0.0.exe,发现第二次启动Eclipse不成功的话,
到Eclipse的plugins目录下,删除文件“com.trolltech.qtcppstartup_1.0.0.jar”即可。
原帖地址:
附:一些主要工具的网址及当前版本下载地址
Eclipse for C/C++
www.eclipse.org
/eclipse/technology/epp/downloads/release/ganymede/SR1/eclipse-cpp-ganymede-SR1-win32.zip
http://sourceforge.net/projects/mingw/
http://nchc.dl.sourceforge.net/sourceforge/mingw/MinGW-5.1.4.exe
http://sourceforge.net/projects/mingw/
http://jaist.dl.sourceforge.net/sourceforge/mingw/gdb-6.3-2.exe
/qt/source/qt-win-opensource-4.4.3-mingw.exe
Qt Eclipse Integration for C++
/developer/download/qt-eclipse-integration-win32-1.4.3.exe
阅读(1133)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
id:'fks_085068',
blogTitle:'windows下发布Qt程序',
blogAbstract:' --&--&--&--&',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:3,
publishTime:4,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}Windows下Qt程序在Linux环境下运行中文乱码解决_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Windows下Qt程序在Linux环境下运行中文乱码解决
来源:Linux社区&
作者:hsl17
1.Windows XP的字体一般存放在c:\windows\fonts目录下,复制你要的字体到Linux下,文件是例如simsun simhai stsong等等的ttf格式文件
2.在Linux下,把字体copy到/usr/share/fonts 目录下,然后执行以下命令:
&&&&&& mkfontscale&&&&&& mkfontdir&&&& //这两条命令是生成字体的索引信息&&&&&& fc-cache&&&&&& //更新字体缓存
/etc/sysconfig/i18n linux乱码问题../etc/sysconfig/i18n
编辑/etc/sysconfig/i18n这个文件,如果没有只能重新拷贝一个了
不管你装的是中文版,还是英文版.删掉原来的配置,把下面的拷贝过去
LANG="zh_CN.GB18030"SUPPORTED="zh_CN.GB18030:zh_CN:zh:en_US.UTF-8:en_US:en"SYSFONT="latarcyrheb-sun16"
相关资讯 & & &
& (08月21日)
& (07月30日)
& (09月09日)
& (08月07日)
& (07月24日)
图片资讯 & & &
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
借夜阑静处 独看天涯星
LOFTER精选
阅读(6750)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
id:'fks_087065',
blogTitle:'QT-Linguist使用方法简单介绍',
blogAbstract:'QT-Linguist工具主要用在项目的多语言翻译处理过程中,所有先简单介绍一下整个多语言处理过程,最后介绍Linguist的用法。(一)QT项目实现多语言,必须做两件事:1)确保每一个用户可见的字符串都使用了tr()函数。2)在应用程序启动的时候,使用QTranslator载入一个翻译文件(.qm)。tr() 的用法:caseCheckBox = new QCheckBox(tr(\"Match &case\"));在main()函数里载入翻译文件:int main(int argc, char *argv[]){& & QApplication app(argc, argv);& & //翻译程序& &QT',
blogTag:'linguist,qt,qm,翻译,ts',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:7,
permalink:'blog/static/',
commentCount:1,
mainCommentCount:1,
recommendCount:1,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'借夜阑静处 独看天涯星',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}1043人阅读
Qt提供的容器类的最大优点在于平台无关性和隐式共享特性
11.1&&&&&&&&Sequentail Containers
QVector& T& array-like data structure(在尾部插入数据时效率很高,而在中间和头部插入数据时开销很大)。
&&&&&&QVector提供了[]运算符
&&&&&&QVector可以用& & 运算符代替append()函数。
&&&&&&QVector中的基本类型及指针被初始化为0。
QLinkedList& T&
&&&&&&QLinkedList不提供[]运算符,所以必须通过迭代器来对其进行遍历。
QList& T&&&&array-list:综合了QVector& T& 和QLinkedList& T& 最重要的优点:
&&&&&&支持[]运算符
&&&&&&在头部或尾部的插入/删除操作很迅速,而尺寸在1000以下时,在中间的插入/删除操作也很迅速。
&&&&&&通常情况下,QList是最合适的通用型容器。
QStringList: QList& QString& 的子类,在Qt中的API中被广泛使用
QStack& T& 和QQueue& T& 是Qt提供的两个convenience subclasses,QStack& T& 实际上是一个额外提供了push(),pop()top()接口的QVector,而 QQueue& T& 实际是一个额外提供了enqueue()和dequeue()和head()的QList。
&&&&&&容器中可以放置的类必须拥有default constructor、copy constructor 和 assignment operator(显式定义或由编译器生成)
&&&&&&注意,派生自QObject的类不符合上述要求,因为其不具备copy constructor和assignment operator;解决方法是在容器中存储对象指针而不是对象本身。
&&&&&&容器中所存放的元素本身也可以是容器,即可以嵌套--不过需要注意将连续的尖括号用空格分隔开,以免编译器误认为& & 运算符。
&&&&&&Qt支持两种风格的迭代器--Java-style和STL-style
&&&&&&Java-style的迭代器更容易使用,而STL-style的迭代器可以同Qt和STL中的算法联合使用,更为强大。
&&&&&&&&Java-style Iterator&&&&&
&&&&&&每个sequential容器类,都有两个Java-style的迭代器类型:只读迭代器和读写迭代器。
&&&&&&在使用Java-style的迭代器时,要清楚的第一件事情就是:迭代器并不直接指向容器中的元素,而是指向元素之前或之后的位置。迭代器被初始化时指向容器中第一个元素之前;若迭代器的右侧有元素存在,hasNext()函数返回true;next()函数返回位于迭代器右侧的元素,并将迭代器向右方移动一个元素的位置;hasPrevious()和previous()函数执行反方向的操作。
&&&&&&remove()函数总是删除最近一次被跳过的那个元素。
&&&&&&setValue()函数总是对最近一次被跳过的那个元素执行更新操作
&&&&&&insert()函数在迭代器当前指向的位置处插入新元素,并将迭代器指向新元素及其后续元素之间的位置。
&&&&&&&&STL-style Iterator
&&&&&&每个sequential容器类,都有两个STL-style的迭代器类型:Container& T& ::iterator和Container& T& ::const_iterator。
&&&&&&容器的begin()函数返回一个指向容器中头部元素的iterator,而end()返回指向容器中尾部元素之后位置的iterator;
&&&&&&在容器为空时,begin()和end()的结果相同。
&&&&&&通常通过调用isEmpty()来检查容器是否为空,而不是通过比较begin()和end()的结果。
&&&&&&可以对STL-style的iterator使用+、-、*这三个运算符,类似于指针的用法。
&&&&&&某些Qt函数的返回值是容器类;如果需要使用STL-style的迭代器来对这样的返回值进行遍历,必须保存返回值的一个副本,并在副本上完成遍历,否则会可能会导致所谓的& dangling iterator& 。
&&&&&&注意,若使用java-style的只读迭代器,在这种情况下会隐式的完成复制的工作,保证迭代器总是在副本上进行遍历操作。
implicit sharing(copy on write)
&&&&&&Qt中的implicit sharing机制的美妙之处在于它鼓励程序员在返回对象时采用传值这种简明的方式而不是引用或指针。
&&&&&&STL与此相反,鼓励程序员使用non-const引用来传递vector以避免将函数返回值的复制开销。
&&&&&&Qt中所有的容器都采用了implicit sharing机制;此外很多其他类QByteArray,QBrush,QFont,QImage,QString也采用了该机制--这保证这些类在以传值方式进行传递时有很高的效率,无论是作为参数还是函数返回值。
&&&&&&在Qt提供的implicit sharing机制下,对vector或list执行只读操作时,采用at()而不是[]运算符是一个更好的选择。
&&&&&&类似的,尽可能的使用constBegin()和constEnd()以避免不必要的拷贝操作。
foreach syntax
&&&&&&foreach在进入循环体时自动复制容器的副本并在此副本上进行迭代,因此如果迭代过程中有通过迭代器对容器的修改操作的话,并不会影响循环的进行,循环结束后容器的内容也不会发生变化。
&&&&&&当然,如果在foreach循环中直接使用[]运算符对容器进行写操作的话,容器的内容自然会发生变化。
&&&&&&&&&&&&&&&&&
&&&&&&foreach中支持break和continue语句
11.2&&&&&&&&Associative Containers
&&&&&&QMap中的key-value对是升序排列的
&&&&&&插入和删除操作中都可以使用[]运算符,其下标为key;为避免创建不必要的空值,推荐用vlaue()而不是[]从QMap中取值。
&&&&&&QMap& K,T& 中的K和T除了要求具备默认构造函数、拷贝构造函数和赋值运算符外,K还必须支持operator & ,因为这样才能实现前面提到的升序排列。
&&&&&&keys() & values()
&&&&&&QMap的特性是单值;QMultiMap& K,T& 则支持同一关键字下多值的存在,插入操作由insertMulti()完成
&&&&&&QHash提供的接口和QMap很相似
&&&&&&QHash& K,T& 中的K要符合的额外要求:支持operator ==,并且K可用全局函数qHash()来计算hash value
&&&&&&QHash通常是单值的,而QMultiHash则通过insertMulti()支持多值插入。
QCache& K,T& & QSet& K&
&&&&&&遍历associative containr的最简单方法是使用Java-style的迭代器
&&&&&&foreach syntax也可用于assocaitive container
11.3&&&&&&&&Generic Algorithms
&&&&&&头文件& QAlgorithms& 中声明了一组全局模板函数,用于实现作用于容器的基本算法;多数算法都通过STL-style的迭代器来完成。
&&&&&&STL头文件& algorithm& 中的函数,即可作用于Qt容器,也可作用于STL容器。
&&&&&&qFind(),qBinaryFind(),qFill(),qCopy(),qSort(),qStableSorg(),qDeleteAll(),qSwap()
&&&&&&需要注意的是,qDeleteAll()只对包含指针的容器有意义,该函数将释放所有对象,但并不删除容器中的指针。
11.4&&&&&&&&Strings,Byte Arrays,and Variants
&&&&&&QString,QByteArray和QVariant这三个类和容器类有很多相似之处,在某些场合下可作为容器类的替代品;和容器类一样,这三个类也应用了implicit sharing 机制
QString&&&&&
&&&&&&QString中存放的是16-bit的Unicold值。
&&&&&&从概念上,QString可以看成是QVector& QChar& 。
&&&&&&QString提供+/+=运算符以及append()函数用于合并字符串
&&&&&&QString提供的sprintf()函数,与C++标准库中的sprintf支持相同的参数格式。
&&&&&&QString提供的arg()函数,是比sprintf()更好的选择,因为它保证类型安全,支持unicode。
&&&&&&QString::number(): number-& string
&&&&&&QString::setNum(): number-& string
&&&&&&反向的转换接口:toInt(),toLongLong(),toDouble()等,这些函数都有一个可选参数--bool类型的指针,若转换失败则将该bool变量置为true,否则置false.
&&&&&&mid()函数返回指定区间内的子串;left()和right()函数则分别返回左子串和右子串
&&&&&&QString的indexOf()函数可用于文本匹配,返回所匹配子串的起始下标;匹配失败时返回值为-1。
&&&&&&startsWith()和endsWith()函数可用于判断字符串的首部和尾部是否符合某种模式。
&&&&&&QString在进行比较时是大小写敏感的;当所比较的字符串是用户可见时,使用localeAwareCompare()通常是正确的选择。
&&&&&&toLower() & toUpper()
&&&&&&replace() & remove() & insert()
&&&&&&trimmed() & simplified()--这两个函数用于消去字符串中的whitesapce(spaces,tabs,newlines等)
&&&&&&QString::split()将一个字符串分割为子串,并返回由这些子串们组成的一个QStringList。
&&&&&&QStringList中的所有元素可以通过join()函数组成一个新的字符串,join()的参数在合并时会被插入相邻元素中间。
&&&&&&在大多数情况下,由const char * 至QString的转换是自动的。
&&&&&&反方向的转换,可通过toAscii()或toLatin1()来完成;这些函数返回一个QByteArray,其可以通过QByteArray::data或QByteArray::constData()来转换为const char * ;
&&&&&&为了简化转换,Qt提供了一个qPrintable()宏用于完成与toAscii()以及constData()相同的操作。
QByteArray
&&&&&&QByteArray提供的API与QString的很相似。
&&&&&&QByteArray的用处在于存储原始2进制数据及8-bit编码的字符串。
&&&&&&通常选择QString而不是QByteArray来存储文本信息,因为QString支持Unicode。
&&&&&&QByteArray会自动在最后一个元素之后补上‘/0',这样使得将QByteArray传递给需要const char *的函数变得很容易。
&&&&&&QByteArray支持'/0',允许存储任意的2进制数据。
&&&&&&QVariant类可用于存放很多Qt类型的值,并且还可以存放容器。
&&&&&&QVariant在 item view class,database model 和QSetting中被广泛的使用着。
&&&&&&利用QVariant和嵌套,可以创建非常复杂的数据结构。
&&&&&&QVariant的便利性是以性能和代码的可读性为代价的。
&&&&&&QVariant被Qt的meta-object system所使用,因此是Qtcore module的组成部分。
&&&&&&&&&&&&&&&&&
&&&&&&QVariant也可以支持用户自定义的数据类型,前提是该类型具有defalut constructor和copy constructor。要实现对用户自定义类型的支持,需要使用宏Q_DECLARE来注册该类型。
&&&&&&全局函数:qVariantFromValue(),qVariantValue& T& (),qVariantCanConvert& T& ()
Chapter 12 Input/Output
&&&&&&Qt通过QIODevice类,对支持块读写的设备进行了强有力的抽象和封装,从而提供了良好的I/O支持。
&&&&&&Qt中提供的QIODevice的子类包括QFile,QTemperorayFile,QBuffer,QProcess,QTcpSocket和QUdpSocket.
&&&&&&QProcess,QTcpSocket和QUdpSocekt属于sequential device,即数据只能被访问一次,且只能按照顺序读取;而QFile、
QTemporaryFile和QBuffer属于random-access device,数据可以被访问任意次,且可以从任意位置开始读取;
&&&&&&除了以上的device class,Qt还提供了两个可用于读写任何设备的高层数据流类:用于二进制数据的QDataStream和用于文本的QTextStream。这两个类负责处理字节序和文本编码等问题,保证运行在不同平台或不同国家的Qt程序能正确读取彼此的文件。这使得Qt的I/O类比起C++标准库中的I/O类更方便--它将这些问题留给了程序员来处理。
&&&&&&QProcess允许程序员调用外部程序并通过标准输入流、标准输出流和标准错误流与其进行通讯。默认情况下,进程之间的通讯是异步的,但也可以在某些操作上阻塞。
12.1&&&&&&&&Reading and Writing Binary Data
&&&&&&Qt中载入和保存二进制数据最简单的方法就是使用QFile来打开文件,并通过QDataStream对象来访问文件内容。
&&&&&&QDataStream对象的version number直接影响着Qt中的数据类型以何种方式表示和记录。C++的基本类型保证总是以同一种方式表示和记录,不受verson number的影响。
&&&&&&在使用QDataStream时,需要保证在读文件和写文件时使用相同的number version。
&&&&&&若QDataStream被用来单纯读写C++基本类型的数据,那么没有必要调用setVersion()来设定version number
&&&&&&QDataStream的默认字节序是big-endian,这可以通过调用setByteOrder()改变。
&&&&&&使用Qt时,通常没有必要显式执行关闭文件的操作,因为QFile在销毁的时候会自动执行文件的关闭操作。
&&&&&&&&可以调用flush()来强制完成数据的写操作。
&&&&&&QDataStream存储数据的方式能保证可以无缝的将其再次读出,例如,一个QByteArray对象的存放形式是一个32-bit的计数值后跟数据本身。
&&&&&&可以使用readRawData()和writeRawData()来读写原始字节。
&&&&&&使用QDataStream读数据时的错误处理是很简单的,status()函数返回当前状态,包括QDataStream::Ok、QDataStream::ReadPastEnd和QDataStream::ReadCorruptData。
&&&&&&当有错误发生时,& & 运算符的返回值总是0值或是空值。
&&&&&&为自定义类型提供& & 和& & 运算符有很多好处:可以对包含该自定义类型的容器使用QDataS 可以将该自定义类型的数据通过QVariant保存起来,这需要先调用qRegisterMetaTypeStreamOperators& T& ()宏。
&&&&&&&&&&&&&&&&&
&&&&&&如果希望一次性读/写文件,可以放弃QDataStream与QIODevice子类的联合使用,而用QIODevice提供的write()和readAll()接口来直接进行读写操作。
&&&&&&QIODevice()提供的peek()函数返回下一个待读取的数据,而不改变读写指针,该接口对于random-access device 和sequentail device 都适用。
&&&&&&对于random-access,可以使用seek()来指定读写指针的位置。
12.2&&&&&&&&Reading and Wrinting Text
&&&&&&Qt提供了QTextStream来读写文本格式的文件,如plain text,HTML,XML,source code等。
&&&&&&QTextStream负责完成Unicode与系统本地编码之间的转换,并自动处理不同操作系统之间换行符不同表示方式上的转换(如在windows下是/r/n,在linux是/n)。此外还自动完成C++基本数字类型与字符串之间的相互转换。
&&&&&&&&&&&&&&&&&
&&&&&&QTextStream使用QChar作为基本的数据单元。
&&&&&&写文本数据非常容易,然而读文本则可能非常具有挑战性,因为文本数据在本质上是具有歧义性的。
&&&&&&默认情况下,QTextStream使用本地编码来进行读写操作;可以调用setCodec()改变之,如stream.setCodec(& UTF-8& );
&&&&&&Qt仿照C++的I/O库为QTextStream也提供了stream manipulators。
&&&&&&同QDataStream一样,QTextStream在一个QIODevice之上进行操作;除此之外还可以在QString上进行操作,这种情况下不需要为流设置编码格式,因为QString总是Unicode。
&&&&&&如果只读写ASCII字符集和Latin-1字符集的文件,可以直接使用QIODevice提供的API进行读写,而不用使用QTextStream。通常这并不是一个好主意,因为这不利于国际化和后期维护。
&&&&&&如果真的需要直接向QIODevice写文本,在使用open打开该QIODeveice时必须指定QIODevice::Text标志;该标志的作用在于告知QIODevice,在写文本数据时,在windows平台上将所有/n转换为/r/n;而在读文本数据时,在所有平台上忽略/r。
12.3&&&&&&&&Traversing Directories
&&&&&&QDir提供了一种平台无关的方法用于获取文件信息以及遍历目录。
&&&&&&QDir::entryList()&&&&&&&&其第二个参数表明要读取目录下的那些条目--文件(QDir::Files)还是子目录(QDIr::Dirs)等。
&&&&&&&&&&&&&&&&&
&&&&&&QDir::separator()&&&返回当前平台上的目录分割符QDir在所有平台上都将'/'视为目录分割符,在windows平台上还额外的识别'/'。
&&&&&&QDir::currentPath()&&返回程序当前目录的绝对路径
&&&&&&QDir::homePath()&&&&返回用户的主目录路径
&&&&&&&&&&&&&&&&&
&&&&&&QFileInfo类允许程序员获取文件的属性信息,如大小,访问权限,所有者及各种时间戳等。
12.4&&&&&&&&Embedding Resources
&&&&&&Qt允许在程序的可执行文件中嵌入二进制或文本文件,这是通过Qt的资源机制实现的。
12.5&&&&&&&&Inter-process Communication
&&&&&&QProcess类允许运行外部程序并与其通讯。该类异步工作,在后台完成相应的工作来保证UI对用户操作的正常响应,在外部程序终止或有数据产生时emit signal来通知本程序。
&&&&&&QProcess::start()用于传递必要的参数,并启动外部程序。
&&&&&&静态函数QProcess::execute()会运行一个外部程序并在外部程序结束之前保持阻塞状态。
&&&&&&QTemporaryFile::open()在无参数时以读写模式打开文件。
&&&&&&QTemporaryFile在对象生存期结束时会自动删除临时文件。
&&&&&&当QProcess以同步模式使用时,不需要建立signal-slot连接。
&&&&&&如果需要比静态函数execute()精度更高的控制,可以改用下面的方法:
&&&&&&首先创建一个QProcess对象,然后对其调用start(),之后调用QProcess::waitForStarted()强制进入阻塞状态,直至外部程序顺利启动为止,之后再调用QProcess::waitForFinished(),阻塞直至外部程序结束为止。
Chapter 13 Databases
&&&&&&QtSql模块提供了一个平台无关、数据库无关的访问SQL数据库的接口。
&&&&&&Qt中的每个数据库连接用一个QSqlDatabase对象来表示;Qt使用不同driver来和各种不同数据库的API进行通讯。
&&&&&&QSqlQuery提供了直接执行任意SQL语句的特性;此外还提供了两个高层次的无需SQL命令的数据库接口:QSqlTableModel和QSqlRelationalTableModel
13.1&&&&&&&&Connecting and Querying
&&&&&&在执行SQL命令前,必须先建立好同数据库的连接。
&&&&&&静态函数QSqlDatabase::addDatabase()用于创建一个新的QSqlDatabase对象,函数的第一个参数指定了Qt该选择哪个Driver来访问数据库。
&&&&&&对QSqlDatabase对象设定好host name,database name ,username和password后,需要调用open()函数建立到数据库的连接。
&&&&&&一旦到数据库的链接建立好后,就可以通过QSqlQuery::exec()来执行底层数据库所支持的任意SQL语句了。
&&&&&&QSqlQuery::next()返回查询结果集中的下一行,而QSqlQuery::value()则返回当前行中的某一项的值,以QVariant的形式返回。
&&&&&&可以使用QSqlQuery::isActive()来检查SQL语句的执行是否出现错误。
placeholder
&&&&&&QSqlQuery::prepare()
&&&&&&QSqlQuery::bindValue() or QSqlQuery::addBindValue()
&&&&&&QSqlQuery::exec()
&&&&&&Qt支持数据库中transaction(事务)这个概念。transaction()用于启动transaction,而commit()或rollback()用于结束transaction。
&&&&&&静态函数QSqlDatabase::database(),返回指定连接所对应的QSqlDatabase对象。
&&&&&&QSqlDatabase::driver() 返回该连接底层所使用的dirver
&&&&&&QSqlDatabase::hasFeature()可用来查询底层数据库是否支持某项特性。
&&&&&&Qt允许在一个程序中创建多个数据库连接,这种情况下在执行SQL语句时,需要为QSqlQuery对象的构造函数传入要执行该语句的数据库对应的QSqlDatabase对象。
&&&&&&与QSqlQuery相比,QSqlTableModel提供了一个更高层次、更抽象的接口,可以避免使用原始的SQL命令。
&&&&&&QSqlTableModel::record() & QSqlTableModel::value()
&&&&&&QSqlTableModel::insertRow() & QSqlTableModel::setData()
&&&&&&QSqlTableModel::submitAll() ,与其他model不同,在使用QSqlTableModel时,必须调用submitAll()来强制所有的修改都写入数据库。
&&&&&&当需要处理外键foreign key时,需要使用QSqlRelationalTableModel而不是QSqlTableModel。
&&&&&&对于使用了SQL相关类的应用程序,需要在对应的.pro中添加下面一行:& QT&&&&&&&&+=sql& ,这样在链接时会将QtSql库链入。
Chapter 14. Networking
14.1&&&&&&&&Wrinting FTP Client
&&&&&&QFtp是Qt提供的封装了ftp协议的一个类。
&&&&&&Qftp的所执行的操作是异步完成的,这保证了FTP命令在执行过程中UI处于可相应状态。
&&&&&&当程序不需要链入QtGui库时,可以在main()中创建QCoreApplication对象而不是QApplication对象。
&&&&&&QCoreApplication::argurments() 函数以QStringList的形式返回程序的命令行参数,其中第一个参数为程序名,并且所有与Qt相关的参数例如-style都已经被移除掉了。
&&&&&&QUrl是Qt提供的一个用于从url中提取各种信息的一个高层接口。
&&&&&&提交的FTP命令被排队,并在Qt的event loop中被执行;QFtp对象在它处理完所有请求后会emit done(bool) 这个signal,其中类型为bool的参数表明是否有错误发生。
&&&&&&QFtp所封装的Ftp命令包括 connectToHost(),login(),close(),list(),cd(),get(),put(),remove(),dir(),mkdir(0,rmdir() 和rename()。 这些函数都返回一个标记命令的ID。
&&&&&&TransferMode()可用于改变传输模式,默认为passive;TransferType()用于改变传输类型,默认为binary。
&&&&&&此外,还可以通过rawCommand()来执行任意标准ftp命令,如&(& SITE CHMOD 755 fortune& );
&&&&&&QFtp在开始执行每条FTP命令时都会emit commandStarted(int)这个signal,并在每条FTP命令完成时emit commandFinished(int,bool) 这个signal,其中int 参数是命令对应的ID,而bool参数则表示是否有错误发生。
&&&&&&QFtp在每当ftp连接的状态发生改变时会emit stateChanged() 这个signal,这里的状态包括QFtp::connecting、QFtp::connected、QFtp::LoggedIn等。
&&&&&&每当命令队列变为空时,QFtp都会emit done(bool)这个signal。
&&&&&&当有错误发生时,Qftp自动将命令队列清空。
&&&&&&若要使用QFtp,需要在项目的.pro文件中添加下面一行:& Qt&&+=network&
&&&&&&listInfo(),每当QFtp执行list()命令得到一个目录项时,都会emit 这个signal
&&&&&&QFtp的get()函数在调用时可以不给出要写的设备,这种情况下QFtp会在有新数据可用时emit readyRead()这个signal ,程序员可以调用read或readAll()这两个接口用于读数据。
14.2&&&&&&&&Writing HTTP Clients
&&&&&&与Ftp协议相对应,Qt为Http协议提供了QHttp类。
&&&&&&QFtp和QHttp在接口和特性上有很多相似之处。
&&&&&&QHttp同样是异步工作模式。
&&&&&&QHttp在开始执行request命令时emit requestStarted(int)这个signal,而在request操作结束时emit requestFinished (int,bool)这个signal,其中int参数和bool参数的含义与QFtp中的类似。
&&&&&&当有错误发生时,请求队列被自动清空。
&&&&&&与QFtp相同,QHttp也提供了readyRead()信号和read()、readAll()这两个接口函数。
14.3&&&&&&&&Writing TCP Client-Server Applications
&&&&&&QTcpSocket和QTcpServer这两个类用于编写Tcp客户端和服务端
&&&&&&基于TCP的应用程序或者是line-oriented,或者是block-oriented。
&&&&&&QTcpSocket通过对QAbstractSocket的继承而成为QIODevice的子类,因而可以使用QDatatStream或QTextStream来对其进行读写。
&&&&&&QTcpSocket在有数据可读时会emit readyRead()这个signal。
&&&&&&Qt中提供的forever syntax等同于 for( ; ; )
&&&&&&QTcpServer类允许接受外来TCP连接,每当检测到外来TCP连接请求时,会自动调用QTcpServer::incomingConnection()函数,参数为标识socket ID的int型变量。
&&&&&&QTcpSocket::listen()用于完成监听工作。
&&&&&&QTcpSocket提供的canReadLine()和readLine()这两个函数对于line-oriented应用程序提供了很大的便利。
14.4&&&&&&&&Sending and Receiving UDP Datagrams
&&&&&&不同于QTcpSocket,QUdpSocket不支持主机名而只支持主机地址。
&&&&&&将主机名转换为IP地址,有两种选择,一是使用静态函数QHostInfo::fromName(),该函数是阻塞的;二是使用静态函数QHostInfo::lookupHost(),该函数是非阻塞的。
&&&&&&QUdpSocket::bind()
&&&&&&readyRead() signal
&&&&&&QUdpSocket将收到的datagram排队,并允许客户一次访问一个datagram。
Chapter 15 XML
&&&&&&Qt中的QtXml模块提供了两组不同的API用于读取XML文档
&&&&&&SAX(Simple API for XML):通过virtual function直接向应用程序报告& parsing event“。
&&&&&&&&DOM(Document Object Model):将XML文档转换为树型结构。
&&&&&&SAX接近底层,速度更快;DOM更便于使用。
15.1&&&&&Readin XML with SAX
&&&&&&SAX是事实上的读取XML文档的标准API,Qt中的SAX类仿照了Java中的SAX2的实现。
&&&&&&Qt提供了一个SAX-based的non-validateing类型的XML解析器QXmlSimpleReader。解析器在读取文档时,会调用其注册的handler class中的virtual function。
&&&&&&Qt为QXmlSimpleReader提供了若干handler class,对于大多数应用,只需要使用QXmlContentHandlerr和QXmlErrorHandler。
&&&&&&Qt提供了一个对程序员很方便的QXmlDefaultHandler,它对所有的handler class都进行了派生,并对所有virtual function提供了简单的实现。
&&&&&&要使用QtXml库,需要在.pro文件中加入下面一行: & QT&&&&+=xml&
15.2&&&&&&&&Reading XML with DOM
&&&&&&DOM是由W3C制订的解析XML的标准API,Qt提供了一个non-validating类型的DOM level 2级别的实现,可用于XML文档的读写以及其他操作。
&&&&&&DOM在内存中将XML文件表示为树的形式。
&&&&&&QDomDocument::setContent(),设定要读取的XML文档。
15.3&&&&&&&&Writing XML
&&&&&&Qt中存在两种生成XML文档的方法
&&&&&&1).&&&&&&&&构建一个DOM tree,并对其调用save()
&&&&&&2).&&&&&手动输出XML格式
&&&&&&两种方式之间的选择独立于读取XML文档时选择SAX或是DOM
&&&&&&默认情况下,QDomDocument::save()生成文档时采用UTF-8编码格式。
Chapter 16 Providing Help
&&&&&&QWidget::setToolTip()用于为Widget设置相应的tip文本。
&&&&&&同样,QAction::setToolTip()为Action设置相应的tip文本;若没有显式的为Action设置tip文本,Action会自动的使用action text。
&&&&&&setStatusTip(),该函数为Widget和Action添加 status tip。
&&&&&&QTextBrowser类能解析大量HTML标签,可用于显示基于HTML的文本内容
&&&&&&Qt Assistant支持索引和文本搜索功能,可以很好的用于提供在线帮助
&&&&&&要使用Qt Assistant,必须在程序中书写必要的代码让Qt Assistant能察觉到文档的所在。
&&&&&&Qt程序与Qt Assisant之间的通讯是由QAssistantClient这个类来负责的;该类属于一个单独的类库,要使用该类库,需要在.pro中添加下面一行: CONFIG&&&&&&&&+=assistant
&&&&&&QAssitantClient类的构造函数以文件路径作为首个参数,用于确定 Qt Assistant可执行文件的位置。
Chapter 17 Internationalization
&&&&&&Qt4为国际化内置了很多良好的支持:
&&&&&&1).&&&&&&&&Qt的API接口和内部实现均是基于Unicode的
&&&&&&2).&&&&&&&&Qt的文本引擎支持所有的non-Latin的书写系统,包括阿拉伯、中日韩、希伯来、印度、泰国等。
&&&&&&3).&&&&&&&&Qt的layout 引擎为right-to-left风格的阿拉伯文和希伯来文提供了相应的支持。
&&&&&&4).&&&&&&&&某些语言在输入文本时需要使用专用的输入法,QLineEdit和QTextEdit可以和系统中安装的任意输入法协调工作。
&&&&&&Qt提供了用于文本翻译的GUI工具:Qt Linguist,以及两个辅助命令行程序 lupdate和lrelease。
&&&&&&大多数程序都是在启动阶段就根据用户的locale setting加载合适的translation file,然而某些情况下用户要求能够在运行时实时的切换界面语言。
17.1&&&&&&&&Working With Unicode
&&&&&&QString以Unicode来存储字符串,QString中的每个字符都是一个16-bit的QChar而不是8-bit的char。
&&&&&&对QString中的某个位置进行赋值操作,可以通过字符方式来确定新值,也可以通过数值方式来确定,例如要将类型为QString的str的首字符设为'A',可以有下面两种方式:
&&&&&&str[0]='A';
&&&&&&str[0]=QChar(0x41);
&&&&&&基于QChar之上的编程不同于基于char。要获得一个QChar变量的编码值,对其调用unicode()函数;要获得一个QChar变量对应的 ASCII或Latin-1编码值,对其调用toLatin1(),若原来QChar中存放的是non-latin字符,该函数返回'/0'。
&&&&&&Qt为QChar类提供了基于Unicode的判断函数,如isPrint(),isSpace(),isLetter(),isNumber()等,其工作与C++标准库提供的isalpha(),isdigit(),isspace()类似。
&&&&&&Qt负责将Unicode编码的QString正常显示,并在需要和其他系统进行通讯时转换为相关的编码格式。
&&&&&&默认情况下QTextStream使用系统本地的8-bit编码格式(可通过调用QTextCodec::codecForLocale()查看)读写文本文件,对于美国和西欧,这通常意味着使用Latin-1。
&&&&&&可以调用QTextStream::setCodec()来自定义读写文件时所使用的编码,如 stream.setCodec(& UTF-16& );
&&&&&&UTF-16格式与QString的内存表示一致,因此使用UTF-16读写Unicode字符串速率会很高,缺点是在存储纯ASCII数据时会有较大的开销。
&&&&&&setCodec()的参数是一个合适的QTextCodec对象,由其负责完成Unicode和本地编码之间的转换。
&&&&&&QTextCodec::codecForName():根据参数中给出的编码名称返回对应的QTextCodec对象。
&&&&&&在读文本文件时,默认情况下QTextStream能够自动检测Unicode编码(依据是0xFFFE,这个Unicode byte order mark);可以通过调用setAutoDetectUnicode(false)来关闭该特性。
&&&&&&默认情况下,Qt将传递给函数tr()的参数视为Latin-1编码的字符串;可以调用静态函数QTextCodec::setCodecForTr()来改变该默认设置,而自定义编码方式。注意,这必须在第一次调用tr()之前就完成。
&&&&&&然而即便如此,代码中的其它显式字符串仍会被解释为Latin-1字符串;解决方法之一是利用QTextCodec对象的toUnicode()函数,也可以调用QText::setCodecForCStrings()来告知Qt在const char*与QString之间进行转换时采用何种编码。
17.2&&&&&&&&Making Applications Translation-Aware
&&&&&&要实现程序的多语言化,需要完成两件事情:
&&&&&&1).&&&&&&&&确保程序中每个用户可见的字符串都被tr()处理。
&&&&&&2).&&&&&&&&确保程序启动时加载translation file(.qm)。
&&&&&&tr()是在QObject中定义的静态函数,并且在每个使用了Q_OBJECT宏的子类中都被overridden。
&&&&&&tr()返回字符串的一个翻译版本,如果存在的话;否则将输入参数原样返回。
&&&&&&要准备transaltion file,需要使用Qt提供的lupdate,该工具将代码中所有出现在tr()中的可见字符串提取出来并生成待翻译的translation file,这样的translation将发送给翻译者来完成翻译工作。
&&&&&&调用tr()函数的一般形式为
&&&&&&Context::tr(sourceText,comment);
&&&&&&其中Context是tr()所属的类,comment是可选参数,用于为翻译者提供附加信息。
&&&&&&当在一个全局函数中调用tr()时,必须显式的指明相应的Context(类)。
&&&&&&QApplication::translate() 函数完成与tr()函数相同的工作。
&&&&&&tr()和QApplication::translate()完成双重工作:一方面供lupdate从中提取用户可见字符串,另一方面从translation file中提取字符串的对应翻译。
&&&&&&尽管对一个字符串变量而不是字符串常值调用tr()并不是个好主意,然而实际上也是可以作到的,这需要在将字符串常值赋值给某个字符串变量时调用QT_TR_NOOP()宏,该宏不进行任何操作,只是为lupdate提供标识。宏QT_TRANSLATE_NOOP完成同样的工作,不同之处在于参数中可以指定context,这对于初始化类外变量很有用。
&&&&&&如何能确保程序员在编写代码时将所有用户可见字符串用tr()包裹起来而不出现遗漏呢?可以通过在包含任何Qt头文件之前定义预定义符号 QT_NO_CAST_FROM_ASCII这个来告诉Qt禁止从const chat * 到QString的自动转换;通常在.pro文件中添加下面一行:
“DEFINES&&&&&&+=QT_NO_CAST_FROM_ASCII& 来实现这一定义。
&&&&&&这样就强迫每个字符串常量在使用时必须被tr()或QLatin1String()函数包裹从而转换为QString,这取决于该字符串常量是否需要被翻译。
&&&&&&静态函数QLocale::system()返回一个QLocale对象,以提供用户的locale信息。
&&&&&&QTranslator对象只能一次加载一个translation file;通过使用多个QTranslator对象,Qt程序可以安装任意数量的
QApplication在寻找合适的翻译时会使用所有已安装的QTranslator。
&&&&&&QTranslator::load()用于加载translation file (.qm)
&&&&&&QApplication::setLayoutDirection(),该函数可以改变文本的书写方向。
&&&&&&QLocale类提供本地化的数字和日期/时间格式。
17.3&&&&&&&&Dynamic Language Switching
&&&&&&当Qt检测到环境变量中的locale设置发生变化时,会创建一个LocalChange event;若要处理该event,需要重新实现QWidget::changeEvent()。
&&&&&&当QApplication上已安装的QTranslator的内容发生变化时,Qt会创建一个LanguageChange event。
&&&&&&不要将LocalChange和LanguageChange两个event混淆;前者的发生是由系统变化导致的,所通知的对象是Qt应用程序;后者的产生是Qt自身导致的,所通知的对象是程序的widgets。
17.4&&&&&&&&Translating Applications
&&&&&&翻译的三个步骤:
&&&&&&1).&&&&&&&&开发人员运行lupdate程序从源代码中提取用户可见字符串,并创建XML格式的.ts文件
&&&&&&2).&&&&&翻译人员运行Qt linguist这个GUI工具,完成文本的翻译工作
&&&&&&3).&&&&&&&&开发人员运行lrealease这个工具,生成应用程序可以通过QTranslator加载的二进制.qm文件
&&&&&&lrelease的工作就是将可读文本的.ts文件转换为二进制的.qm文件。
&&&&&&lupdate默认情况下假设所有tr()中的字符串都采用Latin-1编码;若实际情况并非如此,需要在.pro文件中添加CODECFORTR这一项;该工作和在程序中调用QTextCodec::setCodecForTr()二者是缺一不可的。
18.1&&&&&&&&Creaing Threads
&&&&&&Qt中提供多线程的机制很简单:创建QThread的派生类,并重新实现其保护成员函数run()。
&&&&&&QThread::run(),被调用来开始线程的执行,在run()结束时线程终止。
&&&&&&QThread::terminate(),用来终止线程的执行,非阻塞操作,并不保证线程的立即终止;可以在调用QThread::terminate()之后调用QThread::wait()来实现同步等待。
&&&&&&terminate()并不是值得推荐结束线程的方法,因为它强制线程终止而不给线程任何清场的机会。
18.2&&&&&&&&Synchronizing Threads
&&&&&&Qt提供的用于线程同步的类包括QMutex,QReadWriteLock,QSemaphore和QWaitCondition
&&&&&&QMutex::lock()&&&&&&&&&&&&&&&&&&&&阻塞操作
&&&&&&QMutex::trylock()&&&&&&&&&&&&&&非阻塞操作
&&&&&&QMutex::unlock()&&&&&
&&&&&&QMutexLocker是Qt提供的用于简化Mutex操作的一个类--QMutexLocker的构造函数以一个QMutex对象为参数,并对其自动执行lock操作;而在析构函数则对其自动执行unlock操作。
QReadWriteLock可以允许同时进行多个读操作或一个写操作。
&&&&&&QReadWriteLock::lockForRead()
&&&&&&QReadWriteLock::lockForWrite()
&&&&&&QReadWriteLock::unlock()
QSemaphore是对Mutex的扩展;与读写锁不同的是,信号量可以用来保护一批相同的资源,而不只是一个。
&&&&&&QSemaphore::acquire(int n=1)
&&&&&&QSemaphore::release(int n=1)
&&&&&&QSemaphore::available()
QWaitCondition和QMutex联合使用,可以允许一个线程在某个条件满足时唤醒其他线程,比起单独使用QMutex能实现更精确的控制。
&&&&&&QWaitCondition::wait()的参数是一个状态为locked的QMutex,该函数在阻塞本线程前会将这个QMutex解锁,并在函数返回前对其lock。
TLS(thread-local storage)
&&&&&&较好的实现方法是使用QThreadStorage& T& 类,该类常用来实现cache,这样可以避免使用mutex时lock,unlock以及等待带来的开销。
&&&&&&由于某些编译器的问题,QThreadStorage& T& 中只能存放指针。
&&&&&&QThreadStorage::hasLocalData()
&&&&&&QThreadStorage::setLocalData()
18.3&&&&&&&&Communicating with MainThread
&&&&&&当Qt程序运行时,主线程是唯一的线程,并且是唯一允许创建QApplication或QCoreApplication对象并对其调用exec()的线程。在调用exec()之后,主线程要么是在等待event的发生,要么是在处理一个event。
&&&&&&主线程可以通过创建QThread的子类来开始新线程。
&&&&&&之前介绍的mutex,read/write lock,semaphore等均可用于新线程之间的通讯,但是却不能用于和主线程的通讯,因为这会导致主循环的event loop被阻塞并& 冻结& UI。
&&&&&&解决方案是在主线程与新线程之间跨线程的使用signal-slot机制。
&&&&&&通常情况下signal-slot机制是同步工作的,这意味着当signal被emit时,与之想联系的slot会被立即调用。
&&&&&&然而,当该机制用于将不同线程中的object连接起来时,则变为异步机制。这样的连接是在底层是通过创建并传递event来实现的;slot被signal的接收对象所在的线程的event loop所调用。
&&&&&&默认情况下,一个QObject对象存在于其被创建的线程之中;这可以在任何时候调用QObject::moveToThread()被改变。
18.4&&&&&&&&Using Qt's Classess in Secondary Threads
&&&&&&Thread-safe & Reentrant&&&&&&&&注意留意这两个概念应用在函数和类之上的不同。
&&&&&&对于类,如果它的所有成员函数都可以被不同线程同时调用而不相互影响--即使这些调用是针对同一个类对象,那么该类被定义为thread-safe。
&&&&&&对于类,如果其不同实例可以在不同线程中被同时使用而不相互影响,那么该类被定义为reentrant;然而,不同线程中同时访问同一个reentrant类对象,并不是安全的,这样的访问需要用mutex进行保护。
&&&&&&在Qt的定义中,在类这个层次,thread-safe是比reentrant更严格的要求,这和在函数层次上的关系正好相反。
&&&&&&通常情况下C++的类只要不使用全局或其它共享变量,就是reentrant的。
&&&&&&Qt中大多数non-GUI的类,是属于reentrant的。QObject是reentrant的,但是需要注意以下几点:
&&&&&&1).&&&&&&&&子QObject必须在父QObject所属的线程中被创建,这意味着在非主线程中的对象在创建时不允许以QThread作为parent,因为后者是在主线程或另外一个非主线程中被创建的。
&&&&&&2).&&&&&&&&在删除一个QThread对象前,必须将对应线程中创建的所有对象都销毁。
&&&&&&3).&&&&&&&&对象必须在其被创建的线程中被删除。
&&&&&&&&如果需要删除存在于另一个线程中的对象,必须调用线程安全的QObject::deleteLater()函数,该函数会发送一个& defered delete& event。
&&&&&&&&QWidget及其子类不是reentrant的。
Chapter 19 Creating Plugins
&&&&&&Qt提供了Qlibrary类,用于以一种平台无关的方式实现在程序运行时加载共享库。
19.1&&&&&&&&Extending Qt with Plugins
&&&&&&Qt本身可以被很多类型的plugin扩展,最常见的包括database drivers,image formats,text codecs等。
&&&&&&对于每种类型的plugin,通常都需要两个类:一个wrapper类实现该类通用的plugin API,以及一个或多个handler类,每个类实现一个plugin特定的API。
&&&&&&在plugin的.cpp文件中,需要使用Q_EXPORT_PLUGIN()这个宏来确保plugin能够被Qt识别。
&&&&&&plugin真正执行的操作都是通过其handler类来实现的。
&&&&&&plugin的.pro文件与应用程序不同。默认情况下.pro文件使用app模板,然而这里必须使用lib模板,因为plugin属于库,而不是一个独立的应用程序。
&&&&&&&&&&&
&&&&&&QCoreApplication::addLibraryPath( ),为程序添加新的库路径。
19.2&&&&&&&&Making Application Plugin-Aware
&&&&&&应用程序的plugin实际是实现了一个或多个接口(interface)的动态库。应用程序与plugin之间的通讯是通过interface的virtual table来完成的。
&&&&&&一个接口(interface)通常声明一个virtual析构函数,一个返回QStringList的virtual函数,以及一个或多个其他virtual函数。
&&&&&&在接口声明的尾部,需要调用Q_DECLARE_INTREFACE2()来将该interface与某个标识符关联起来。
&&&&&&QPluginLoader类用于在运行时加载plugin。
&&&&&&QPluginLoader::load(),通常不需要显式调用,因为instance()函数会在必要时调用该函数完成加载。
&&&&&&QPluginLoader::instance(),返回一个指向plugin对象的QObject *指针。
&&&&&&同一个插件plugin可以成功cast至多个interface,因为plugin可以通过多重继承来提供多个interface。
19.3&&&&&&&&Writing Application Plugins
&&&&&&应用程序的plugin是其要提供的interface和QObject二者的子类。
&&&&&&在plugin的源代码中,需要为其提供的每个Interface都要使用Q_INTERFACES()宏,来保证moc和qobject_cast& T& 之间的协调工作。
&&&&&&在.cpp文件的尾部,同样需要调用Q_EXPORT_PLUGIN2()宏来使该plugin对于Qt可用。
Chapter 20 Platform-Specific Features
20.1&&&&&&&&Interfacing with Native APIs
&&&&&&在每个平台上,Qt都为QWidget提供了一个winId()函数,返回window ID或是句柄;QWidget还提供了一个静态函数find(),返回一个特定window ID对应的widget。我们可以将获得的window ID传递给Native API来执行平台特定的操作。
&&&&&&Qt定义了以下系统标志:Q_WS_WIN,Q_WS_X11,Q_WS_MAC,Q_WS_QWS(Qtopia)。
&&&&&&QSysInfo::WindowsVersion&&QSysInfo::MacintoshVersion&&&&&&这两个静态变量存储着WIN和MAC操作系统的版本信息
20.2&&&&&&&&Using ActiveX on Windows
&&&&&&ActiveX构建于Microst COM之上,它为使用组件的应用程序定义了一套接口,为提供组件的库和应用程序定义了另一套接口。
&&&&&&ActiveQt由两个模块组成:
&&&&&&&&&&&&&&QAxContainer模块允许用户使用COM object并在Qt程序中内嵌ActiveX控件。
&&&&&&&&&&&&&&QAxServer模块允许用户导出自定义的COM object以及用Qt编写的ActiveX控件。
&&&&&&Q_ENUMS()宏的作用是告知moc其& 宏参数& 是枚举类型。
&&&&&&QAxContainer模块由三个类组成:QAXObject封装一个COM object,QAxWidget封装一个ActiveX控件,QAxBase为QAxObject和QAxWidget实现核心COM功能。
&&&&&&QAxObject派生自QAxBase和QObject,QAxWidget派生自QAxBase和QWidget。
&&&&&&COM中的数据类型会被自动转换为合适的Qt数据类型。
&&&&&&&&&&&
&&&&&&QAxBase::setControl()
&&&&&&QObject::setProperty()可用于设置COM property和Qt property。
&&&&&&要链接QAxContainer库的话,需要在.pro文件中添加下列一行:& CONFIG +=qaxcontainer&
&&&&&&QAxBase::dynamicCall()
&&&&&&注意,QAxObject和QAxWidget的子类无法定义新的property,signal和slot。
&&&&&&QAxServer模块允许将一个标准Qt程序转换为一个ActiveX server。该server可以是共享库,也可以是独立的应用程序。共享库形式的server被称为in-process servers,而独立应用程序形式的server被称为out-of-process server。
&&&&&&QAxBindable在widget与ActiveX client之间提供了一个接口。
&&&&&&在Qt中处理多重继承中,如果基类中存在QObject的派生类,必须将这样的类放在首位。
&&&&&&QAXFACTORY_DEFAULT()宏的作用是导出一个AxtiveX控件,可以用于仅导出一个控件的ActiveX server;当server要导出多个控件时,不能使用QAXFACTORY_DEFAULT()宏。
&&&&&&QApplication能够识别命令行中的-activex参数,并使应用程序作为server而运行。
&&&&&&Q_CLASSINFO()宏
20.3&&&&&&&&Handling X11 Session Management
&&&&&&为了使一个Qt/X11应用程序意识到session manager的存在,需要重新实现QApplication::saveState()函数,并在该函数中保存应用程序的状态信息。
&&&&&&当用户启动shutdown操作时,程序员可以通过重新实现QApplication::commitData()来获取控制权,这允许应用程序保存未保存的数据,并且与用户交互--如果可能的话;这部分session management在X11和Windows上都被支持。
&&&&&&QObject::setObjectName()
&&&&&&void QApplicatoin::saveState(QSessionManager &)--该函数在session manager希望应用程序保存其状态时被调用,QSessionManager类型的参数允许应用程序与session manager进行通讯。
&&&&&&&&&&&
&&&&&&discard command:是指session manager必须执行的用删除任何存储当前状态信息的命令。
&&&&&&restart command:是指session manager必须执行的用以重新启动应用程序的命令。
&&&&&&QSessionManager::setDiscardCommand(QStringList &)
&&&&&&QSessionManager::setDiscardCommand(QStringList & )
&&&&&&默认情况下,Qt提供的restart command的格式为: appname -session id_key
&&&&&&QSessionManager::release()
&&&&&&QSessionManager::cancel()
&&&&&&QApplication:isSessionRestored()
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:202442次
积分:3511
积分:3511
排名:第3050名
原创:120篇
转载:140篇
评论:64条
(1)(3)(3)(4)(2)(2)(4)(18)(3)(1)(14)(3)(8)(11)(1)(5)(7)(25)(2)(40)(22)(11)(14)(6)(6)(18)(20)(4)(2)}

我要回帖

更多关于 windows运行命令 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信