搭建Qt 5.3.1 for Windows Phone 8开发环境
目前Qt已经支持了Android以及iOS的开发,我也亲自尝试过在Android和iOS上的开发,其中在Android这一块研究的较深,也制作出了第一款独立游戏《吃药了》。在Qt的新版本5.3的发布中,官方宣布支持WindowsPhone 8/8.1的开发。过了两个月了,我也积极尝试一下,看看使用最新的Qt 5.3.1版本如何搭建WP8的开发环境。
原创文章,反对未声明的引用。原博客地址:http://blog.csdn.net/gamesdev/article/details/38568903
1、硬件要求
首先就是硬件了。开发WindowsRT/Windows Phone得天独厚的优势是,我的笔记本是64位的系统,CPU是Intel Core i7-4700MQ四核处理器,内存容量是4G,且运行Windows 8.1操作系统。一般几年前的计算机可能无法胜任这样的开发,因为要支持Windows Phone的开发,CPU必须支持Hyper-V技术。这是微软提出的虚拟化技术,相当于在Windows 8.1下运行Windows Phone虚拟机。有关Hyper-V的要求,我查了一下,CPU必须是64位的,并且支持硬件自我保护(DEP)功能,并且已启动;内存最少2G。我的计算机马马虎虎满足需求,所以能够顺利地进行Windows Phone开发了。
2、软件要求
首先一个要求,就是安装Windows8/8.1操作系统。Windows 7究竟可不可以呢?看了网上的帖子,可能不行……
其次我看了Qt帮助文档的“Qt forWinRT”主题,了解到要支持Windows Phone的开发,需要安装对应的Visual Studio。对于我们关注的Windows Phone 8/8.1,需要安装Visual Studio 2012 for Windows Phone。不过现在是什么时代了,我迫不及待地使用最新版的Visual Studio。于是到这个网站,获取ed2k资源,打开迅雷开始高速下载最新版Visual Studio 14。Visual Studio14在安装的时候有组件的选择,到时候记得选择Windows Phone SDK就好了。
最后Qt是必不可少的,在qt-project.org上下载最新“Qt5.3.1 for Windows RT 32-bit (647 MB)”,然后解压到合适的位置就行了。
安装顺序是VisualStudio 14→Qt 5.3.1 for Windows RT。随后打开Qt自带的Qt Creator。
3、测试第一个程序
首先打开Qt Creator,也就是附带在Qt5.3.1上的IDE。新建一个QML项目,设置构建套件,如下:
生成好的代码如下所示,这里稍作了一些修改:
我这里首先使用桌面的套件构建一下,结果如下所示:
一切正常。
4、开始移植Windows Phone 8
接下来我将尝试将例子程序移植到Windows Phone 8中。如第一张图所示,我们可以选择实体机套件以及模拟器(Emulator)套件。对于没有实体机的同行们来说只能选择Emulator了。当我们按照正常步骤,构建,再运行时,会弹出Windows Phone虚拟机,看起来一切正常:
但是这里有一个坑。过一会儿程序启动后会变得空白一片:
下面也会弹出
qt.winrtrunner:"E:/QtProject/build-TestQuickForWinPhone8-Qt_5_3_for_Windows_Phone_8_x86_MSVC2012_32bit_Emulator-Release/release/AppxManifest.xml"does not exist.
qt.winrtrunner:"E:/QtProject/build-TestQuickForWinPhone8-Qt_5_3_for_Windows_Phone_8_x86_MSVC2012_32bit_Emulator-Release/release/AppxManifest.xml"does not exist.
这样的红字。后面了解到这个问题不影响的。只是我们如何才能显示程序呢?
5、界面,你快回来
“Qt for WinRT”这篇文章讲到了,我们在测试的时候,Qt会提供一个小工具,叫qd3dservice。它可以即时地将着色器编译并呈现给应用程序。因为作为支持Qt渲染的OpenGL,在遇上微软的手机后,不得不“改头换面”,披着Direct3D的外衣来“见”Windows Phone 8手机。于是需要通过Google Code中一个项目ANGLE,将OpenGL ES2.0的着色器代码转换成D3D着色器。刚才无法显示界面,原因是作为界面依赖的着色器没有被载入。
解决方法也很简单,在QtSDK的bin目录下运行不带参数的qtd3dservice就行了。然后再打开我们编译的程序:
这样稍微好一点了,至少我们看到了界面,可是一大堆方块又让我们犯愁了。这又是一个坑那么如何才能让我们看到文字呢?
6、文字,你快回来
看了看Qt 5.3.1for Windows Phone的目录结构,一个显著的不同是在bin和lib文件夹中都有一个名为“font”的目录,这个目录是存放与界面显示相关的字体的。默认打包的时候会包含这些字体。等等,我们刚刚就这样运行程序,可是没有进行打包啊。那么如何进行打包呢?这还得靠我们刚刚安装的VS14。首先定位$${YourProjectDirctory}中,打开命令提示符,输入:
$${QTDIR}/5.3/winphone_x86/bin/qmake -tp vcYourProject.pro "CONFIG+=windeployqt"
我这里是这样的:
运行后,发现uuidgen找不到。这又是一个坑。开始我尽力地去寻找uuidgen.exe,甚至去网上下载了一个uuidgen.exe,并且放在了C:/Windows/system32中,结果都没有起作用!所以说这又是一个坑。不过这个错误并不影响这一步操作,一些必要的Qt和VS项目文件也能够顺利生成。
此时用VS14打开生成的vcxproj文件。如下所示:
此时点击deploy,试试看。结果报错!
C:\Program Files(x86)\MSBuild\Microsoft\WindowsPhone\v8.0\Microsoft.Phone.Packaging.targets(637,9):error : The ‘ProductID‘ attribute is invalid - The value ‘{}‘ is invalidaccording to its datatype ‘http://WPCommontypes:ST_Guid‘ - The Patternconstraint failed.
这就是uuidgen坑人的地方了。因为无法生成ProductID,所以无法部署打包。
当物之急就是能够找到产生uuid的方法。这里有好几种方法。
(1) VS中有一个叫guidgen.exe的工具,和uuidgen只差一个字母。可以用它来产生uuid;
(2) 去网上下载uuidgen.exe,那是1996年微软的老物了,但在命令符下仍然能够产生uuid;
(3) 大家都有Chrome浏览器吧,教大家如何使用Chrome产生uuid。事实上任何js解释器环境都可以,包括QML Engine。打开Chrome,Ctrl + Shift + J,打开JS控制台,然后输入下面的JS代码:
function getGUID( ) { function _p8(s) { var p = (Math.random().toString(16)+"000000000").substr(2,8); return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ; } return _p8() + _p8(true) + _p8(true) + _p8(); } getGUID( );
回车,就能够产生一个合法的uuid了。这里我产生的uuid是:
684cebbf-bb4a-857b-9a1e-746feb967cd3
我们需要做的是,进入项目目录,编辑WMAppManifest.xml,找到ProductID字段,将我们产生的uuid放在大括号里面,保存,这样就好了。
然后进入VS14,点击deploy,然后Ctrl + F5全速运行。记得在运行之前运行qtd3dservice。运行结果如下所示:
大功告成!经过两天的尝试和提问,我终于能够在Windows Phone上面成功地运行Qt程序了。有关Windows Phone上面更多开发方面的问题,有时间我会研究的。
7、总结
这里作一个小小的总结:
1、 Windows Phone应用安装包的后缀是.xap文件,可以用7-zip等压缩解压工具打开,打开后发现和Android的apk安装包的目录结构大同小异。
2、 如上面介绍,用Qt开发WindowsPhone 8还存在很多坑,再比如说这个例子,想点击左上角的File菜单,就不灵敏,有时候Exit选项会独占整个屏幕,显得这个屏幕很空;此外,一些重要的Qt模块比如说我迫切需要的Enginio,并没有一并移植过来。所以说开发Windows Phone 8应用还是实验性的,希望在Qt 5.4中能够做得更好。
3、 如果不希望每次启动qtd3dservice在线编译着色器,那么可以使用“qtd3dservice --list-binary --qrc --device 0 --app {684cebbf-bb4a-857b-9a1e-746feb967cd3}--output /path/to/project/shaders.qrc”来产生shader资源,然后再修改pro文件,添加这一行:“RESOURCES+= shaders.qrc”,最后重新编译打包。
4、 其实qtd3dservice只是一个初步可行的办法,当时考虑Windows的政策不允许JIT编译。我在jira上看到Qt团队讨论的结果是,qtd3dservice将在Qt5.4中移除。因为(1)Windows 8.1支持设备在线(JIT)着色器的编译;(2)qtd3dservice只是一个实验性的解决方案,以后不必维护;(3)可以使用scene-graph采取的cache方法来应用到着色器当中。(参考这里)
5、 即使使用了Hyper-V技术,在模拟器上体验WindowsPhone 8的效果还是比不上真机。我曾经在苏宁电器城中使用诺基亚Lumia 525成功运行Digia的Qt应用Quick Forcast。有条件的话,还是买一台真机进行开发测试吧。