首先声明, 这个文章不是笔者原创。 本文是对一篇技术文章的翻译和整理, 原文出自Trolltech的官方blog中今年三月份发布的这篇文章:
http://labs.trolltech.com/blogs/2009/03/08/creating-a-google-chat-client-in-15-minutes/
(笔者的例子和原例子略有不同, 是根据自己的理解重写的, 有兴趣的同学可以去下载原文中的例子看一看。)
用十五分钟就可以实现一个GTalk的客户端吗? 当然用普通的方法恐怕是不大可能拉, 这里我们会用一种类似“作弊”的方法来实现。
该方法的灵感来源于iPhone提供的一个web appliction, 见, 其核心原理是利用google提供的GTalk的web服务, 外面套上浏览器的外壳, 就成了我们今天要介绍的这个程序了。 用Qt将这种设计思想进行实现, 就是用WebView来显示web服务的内容。
一个典型的GTalk客户端可能会有三个基本的界面: 登录页、联系人列表、聊天页, 这些页面当然优先考虑利用现成的web服务提供的页面。 可惜web服务提供的登录页与一般im软件的登录页面略有不符, 所以我们要自己写一个看上去更像那么回事的界面。 其他的页面用web服务提供的足矣, 只需要调整成合适的尺寸。 根据需求, 我们用一个stackedwidget把登录的界面和webview界面做在一个ui文件里。 另外, 为了界面更友好, 我们添加一个显示载入进度的进度条页面。 就用designer来设计, 不难, 熟手五分钟就可以搞定, 如下图所示:
呵呵, 不要被后面两张图片给吓倒了, 其实里面复杂的内容都是WebView载入的网络内容, 所以在Designer里只需要在界面上放个QWebView控件即可。 我们的代码可以很简单:
1、先载入GTalk web页面, 获得原始数据
2、接受用户输入的用户名和密码,将之发送给GTalk web服务
3、从GTalk服务获取信息, 用Webview显示
4、无。。。
可能与WebKit相关的代码对大家来说还比较陌生, 这里给出各个阶段的关键代码以节省编程的时间:
- 登录页面需要根据逻辑调整焦点和login按钮的状态, 采用的逻辑可以自己来设计, 处理逻辑需要用到几个LineEdit的信号, 如用户输入字符时LineEdit会发送textChanged信号, 而用户按下“Enter”键时发出“returnPressed”信号, 用户点击按钮的时候发出”clicked“信号。
- 利用QWebView的信号来调整需要显示的页面, 如在初始阶段显示进度条页面, web页载入过程中(loadProgress信号)进度条显示载入的进度, 载入完毕后(loadFinished信号)转入登录页面;
*GTalk服务的地址为: #define GTALK_URL “”
*载入初始页面的代码为
m_gtalkui.webView->setUrl((QUrl(GTALK_URL)));
- 登录时需要将参数传送给web服务并获取web服务的回应, 所以需再转入进度条页面显示进度, 载入完毕时转入webview页面。 这段代码需要对GTalk的web服务有一定程度的了解, 比如:
*传参数给web服务使用了GTalk页面的js脚本, 代码为:
evalJS(QString(”document.getElementById(’Email’).value = \”%1\”;”).arg(user));
evalJS(QString(”document.getElementById(’Passwd’).value = \”%1\”;”).arg(password));
evalJS(”document.getElementById(’gaia_loginform’).submit();”);
QString MainWin::evalJS(const QString &js)
{
QWebFrame *frame = m_gtalkui.webView->page()->mainFrame();
return frame->evaluateJavaScript(js).toString();
}
核心的代码就是这些。 如果只是想要一个可以运行的程序, “十五分钟”尚不算是“Mission Impossible”, 不过要把逻辑调整到比较合理的程度还是颇费时间的(笔者就更加不幸, 在和designer和js脚本搏斗的过程中耗费了大量的时间, 所以就不说自己花了多久完成这个例子了, 以免打击大家的积极性。。)。 不如你来试试对照本文和例子代码, 看看你要做一个这样的程序需要多少时间?
webgtalk.tar.gz