存档

文章标签 ‘Webkit’

Thoughts on Flash

2010年4月30日

今天在Apple的主页上明显位置看到了Jobs关于Flash的一篇声明,声明中措辞强烈的列举了6条不使用Adobe Flash技术的原因,包括Flash技术并不开放,Flash对于网站并不算不可或缺,Flash对性能,安全性和稳定性的影响,对于电池的过度消耗,不支持Touch以及Flash开发平台会破坏Apple平台的最新特性。这里我们抛去Apple和Adobe的恩怨不谈,文章里面还是有很多很有意思的信息,我想这些代表了Apple对于未来技术演变的想法,这些也是和Qt紧密相关的,我列举如下:

1. …and created WebKit, a complete open-source HTML5 rendering engine…By making its WebKit technology open, Apple has set the standard for mobile web browsers.

Apple是Webkit的创始者之一,也在一直在对Webkit做出贡献,在Apple看来,Webkit就是未来浏览器引擎的标准,尽管目前IE和Firefox还有很大的市场。

2. …Apple has adopted HTML5, CSS and JavaScript – all open standards…New open standards created in the mobile era, such as HTML5, will win on mobile devices.

Apple是HTML5的最早推动者之一,当然,Google也是,Qt(Nokia)也是。而且Apple认为HTML5迟早会是网络的标准,取代现有的私有框架,例如Flash.

3. …Third, there’s reliability, security and performance…In addition, Flash has not performed well on mobile devices.

Apple认为因为Flash技术本身的限制,Flash在可靠性,安全性和性能方面都存在很大的问题,特别是性能,在嵌入式系统中,Adobe从来没有证明Flash可以很好的运行。

我的看法,无论你同不同意Jobs的看法,也不管Apple有可能有其他的商业目的,但上面的这些原因或者说法都没错。如果Flash还是像现在一样发展,那么HTML5早晚会取代他。而且,回到Qt,我们也是按照Webkit+HTML5+Performance的方向来走,关于这点,我后面会再写一篇。

Qt , , , , , , ,

Code Project:创建一个Qt RSS阅读器

2009年10月30日

我们将构建一个完整的应用程序,使其不必太费事便可重新发布为一个真正的开源应用程序。这个应用程序就是一个RSS阅读器,它允许用户添加自己的种子,列出该种子上的内容,然后让用户在主应用程序自带的一个浏览器窗口中阅读这些内容。

如果你已经尝试过了我们前两个Qt代码项目——创建一个ffmpeg前端创建一个媒体播放器,而且正在寻求更多Qt方面的乐趣,那么请读下去…

RSS是一个以特定方式进行格式化的XML文本文件。它包含对网站上每段内容的简短描述。它最大的优点就是,始终随着新内容的发布而更新。使用RSS阅读器或像Firefox这样与RSS兼容的浏览器时,用户可以从网站订阅RSS种子,而且阅读器将定期检查更新,并列出所有新的内容供用户浏览。而这也正是我们的应用程序所要实现的功能。

它还将引入一些主要的Qt技术,包括处理XML数据流的手段,如何动态填充树视图小部件,以及使用WebKit小部件并将所有小部件组合为一个可动态扩展的、将自动更新为显示web页面的应用程序窗口。这使得RSS阅读器成为启动更多目标远大的项目的最佳起点,即使你马上弃用RSS处理的代码,我们为这个应用程序所构建的可扩展GUI仍然可以发挥作用。

这正是首次运行Qt Creator并创建一个新项目时,需要选择三个单独的模块在应用程序中使用的原因。在向导中点击Qt4 GUI Application模块,给它取一个名字,然后启用如下三个模块:QtNetwork, QtWebkit 和 QtXML。这些模块将紧密联系我们将在本指南中讲到的三个新领域,而且从向导添加它们后,便不用再手动把它们添加到项目的“.pro”文件中。

设计GUI

和我们其他的Qt编程指南一样,在运行Creator创建一个新项目后,接下来要做的工作就是GUI设计。点击“ui”文件打开Designer视图。这一次,我们将采用稍微开放一点的方法进行设计。主窗口将被划分为两个面板。在左侧,我们将添加RSS消息列表,并让用户能够添加他们自己的种子。而窗口的右半部分将是web浏览器,我们将对这部分使用WebKit小部件。

但是Qt的聪明之处在于,我们可以根据用户是否想使用内部浏览器来使每个面板变得可扩展或可隐藏,或者干脆使用他们最惯于使用的浏览器。例如,如果用户不想看到web视图,只需要把中间的分离线拖到右边,它就会消失。这给予了我们的应用程序很大的灵活性,并不强迫想使用自己的浏览器阅读新闻的用户使用web视图。

这项特别的功能是通过Qt中的Dock Widget小部件实现的。当应用程序分为几个部分时,它提供了很强的灵活性,允许用户在四周拖放窗口的不同部分。从Creator页面的Containers列表中拖出两个Dock Widget小部件到空白的应用程序画布上。如果在应用程序中用不着,还可以从Object视图删除多余的菜单、工具栏和状态面板小部件。我们已经添加了两个可停靠小部件,因为我们要在应用程序的两侧使用它们来保存小部件,而且它们是可停靠小部件,用户能够拖动它们之间的分离线,从而改变应用程序每个半区的尺寸。

但在添加更多小部件之前,我们需要确保只启用了每个可停靠小部件的一组有限功能。我们不想让用户完全访问Qt 可停靠小部件更多难以驾驭的功能,KDevelop已经很好地证明了这一点。在Object列表中选择每个可停靠小部件,然后在下面的属性窗口中,确保将选中的“Features”字段设置为“NoDockWidgetFeatures”。这将阻止用户将小部件拖动至窗口外部或者完全关闭它们。你可能想对浏览器面板启用这项功能,这由你自己决定。

a

* 可停靠小部件的优点是,用户可在应用程序运行时改变两侧的比例差异。

小部件面板

在添加其他小部件之前,选择可停靠小部件并点击“Lay Out Horizontally”按钮。接着点击“Lay Out in a Grid”按钮。这样做的效果是同时拉伸跨应用程序窗口的、中间具有一条分离线的两个可停靠小部件。当用户改变主窗口的大小时,这两个小部件将保持它们的相对位置。

尽管网格被锁定,我们仍然能够以常规方式给可停靠小部件添加小部件,而且我们准备从左侧开始。如果在网格被锁定的情况下编辑GUI,Designer将使用蓝色光标突出显示每个小部件要插入的位置,这一点十分类似于字处理器。需要将三个小部件拖动到左边面板中——一个行编辑小部件和一个按钮,它们已经在窗口顶部水平对齐了,还有一个位于下方的树视图。行编辑小部件用于给用户输入RSS种子的URL,按钮用于提交种子给我们的解析器,而树视图用于列出RSS种子的每个入口。

我们给行编辑小部件添加了一个默认的URL。只要双击该小部件,然后输入类似于“http://www.qteverywhere.com/rss”的内容,再将按钮文本改为“Add Feed”。双击树视图,再添加两列,将它们分别取名为“Feed”、“Date”和“URL”。这些列将包含每个新闻内容的信息,但只有“Feed”和“Date”两列可见。这是因为我们要内部使用URL列,不显示给用户看。它将保存内容的URL,这样当用户点击它时,我们可以把URL发送给WebKit。

如果我们不使用这种方法,我们就不得不为应用程序实现一个成熟的MVC解决方案,而这描述起来都超过4页纸了。MVC(模型/视图/控制器)是一种将数据(在这个例子中是指URL)与显示数据的视图分离,同时保持二者联系的方法。后一部分由控制器来处理。当我们使用它的任意容器类时,Qt在后台使用的是MVC,而它用于添加和删除内容项的方法实际上是用于在后台处理MVC的便利函数。我们将在树视图中利用这一点,隐藏URL列并在应用程序中使用数据,但我们只能在源代码中做到这一点。

最后,将WebKit小部件拖动到右侧面板中。这是一个自包含的浏览器窗口,我们不需要添加任何别的内容就可以让它工作。只要保证所有小部件都经过了正确排列,以及你已经在两个面板上使用了一些间距器和“Lay Out in the Grid”模式,从而锁定可缩放窗口的布局。

a

* 在可停靠小部件的左侧,我们添加了树视图,XML 提要的 URL,以及用于从Internet抓取数据的按钮。

连接

既然我们的布局已经最终确定,下一步就要添加槽/信号连接,用于补充我们应用程序的功能。切换到Signals/Slots编辑器,方法是按下F4键或者在工具栏中点击相应按钮。从“Add Feed”按钮拖动一个信号到应用程序窗口的轮廓处,当“Configure Connection”窗口出现时,点击右侧面板上的“Edit”按钮。

我们需要添加两个槽。第一个用于给树视图添加种子,而另一个用于当用户在种子列表中选择一个新闻内容时更新web视图。我们将第一个槽称为“fetch()”,而将第二个槽称为“itemActivated(QTreeWidgetItem*)”。这是我们首次遇到通过信号/槽机制传递的参数,要在设计器中使用它们,必须满足一些严格的规则。其中最重要的一条是,对于一个在传递这类参数时要连接到槽的信号,二者都必须完全支持同一类型。在这个例子中是QTreeWidgetItem类型。

创建这两个槽并将“clicked”连接到“fetch()”之后,从树视图拖一个新连接到窗口背景。我们将看到,很多函数将QItemTreeTree参数作为一个参数包含在内。这是树视图中每一项的类型,以这种方式传递它使我们能够轻松抓取到当前选中的新闻内容的URL,并使用它来更新web浏览器。只要将位于左边的“’itemActivated(QTreeWidgetItem*)”与我们刚刚为自己的应用程序创建的名称相同的新槽连接起来即可。

c

* 这是我们在Creator中建立并用于应用程序中各个函数的SIGNAL和SLOT连接的一个视图。

代码

现在我们已经建立了框架,是时候添加代码了。和我们其他的项目一样,我们从“mainwindow.h”开始,把它作为需要添加我们刚刚在GUI中创建的新槽的地方。我们还准备添加要在程序逻辑中使用的新槽,用于告诉我们的应用程序,从Internet读取web数据的过程已经结束。

     void fetch();
     void itemActivated(QTreeWidgetItem * item);
     void readData(const QHttpResponseHeader &);

现在,我们需要给项目添加一些私有成员。我们将使用这些私有成员管理数据流,并且为解析从站点的RSS种子抓取到的XML数据和HTML数据而创建数据结构。

    void parseXml();
 
    QString currentTag;
    QString linkString;
    QString titleString;
    QString dateString;
 
    QTreeWidgetItem *feed;
 
    int connectionId;
    QHttp http;
    QXmlStreamReader xml;

这是我们需要给头文件添加的内容。我们余下的编码将限制在“mainwindow.cpp”文件中,从位于该文件顶部的初始化函数开始。首先,我们需要在“setupUi”前面添加一个连接行,用于当我们知道Qt的HTTP抓取器已经正确解析HTTP时,自动运行我们的“readyRead”方法。其次,我们想隐藏treeWidget的两列,因为我们只使用这些列来保存数据,而不想让用户看到它们。一旦“setupUi”创建了GUI,我们就可以这样修改它。下面给出相应的代码:

    connect(&http, SIGNAL(readyRead(const QHttpResponseHeader &)), this,
            SLOT(readData(const QHttpResponseHeader &)));
 
    ui->setupUi(this);
 
    ui->treeWidget->setColumnHidden(1, true);
    ui->treeWidget->setColumnHidden(2, true);

现在,我们准备编写fetch()函数。当我们在应用程序中输入RSS种子的URL,然后点击“Add Feed”按钮时,将触发这个函数的功能。

void MainWindow::fetch()
{
        xml.clear();
 
        QUrl url(ui->lineEdit->text());
 
        http.setHost(url.host());
        connectionId = http.get(url.path());
}

这段代码相对较为直观。首先,我们清理了保存XML日期的流读取对象,然后将我们用于保存URL的行编辑组件中的文本转换为一个QUrl,这是Qt中访问在线资源的首选方法。接下来,我们使用这个资源设定QHttp的位置,这个类是用于实现HTTP协议的。我们需要 使用这个类来抓取XML数据,而下一行中使用“get”函数和经过转换的URL调用了这个函数。当“http”成功打开HTTP位置时,它将发出我们前面连接到我们自己的“readData”函数的“readyRead”信号。现在我们需要添加这个函数:

 void MainWindow::readData(const QHttpResponseHeader &resp)
 {
     if (resp.statusCode() != 200)
         http.abort();
     else {
         xml.addData(http.readAll());
         parseXml();
     }
 
 }

这个函数的全部功能就是检查是否找到了URL,如果没有找到,它会中断,而且我们的应用程序也不会再往下执行。但如果远程位置是合法的,在把数据发送给“parseXML”函数之前,我们首先会使用数据填满我们的XML容器——xml.addData(http.readAll())。这是应用程序的一个难点,因为需要遍历从internet抓取的XML树,并把我们需要的数据块放到treeView中。因此,对应代码的篇幅要长很多。

 void MainWindow::parseXml()
 {
 
     while (!xml.atEnd()) {
         xml.readNext();
         if (xml.isStartElement()) {
 
             if (xml.name() == "item"){
 
                 if (titleString!=""){
                    feed = new QTreeWidgetItem;
                    feed->setText(0, titleString);
                    feed->setText(2, linkString);
                    ui->treeWidget->addTopLevelItem(feed);
 
                 }
 
                 linkString.clear();
                 titleString.clear();
                 dateString.clear();
             }
 
             currentTag = xml.name().toString();
         } else if (xml.isEndElement()) {
              if (xml.name() == "item") {
 
                 QTreeWidgetItem *item = new QTreeWidgetItem(feed);
                 item->setText(0, titleString);
                 item->setText(1, dateString);
                 item->setText(2, linkString);
                 ui->treeWidget->addTopLevelItem(item);
 
                 titleString.clear();
                 linkString.clear();
                 dateString.clear();
             }
 
         } else if (xml.isCharacters() && !xml.isWhitespace()) {
             if (currentTag == "title")
                 titleString += xml.text().toString();
             else if (currentTag == "link")
                 linkString += xml.text().toString();
             else if (currentTag == "pubDate")
                 dateString += xml.text().toString();
         }
     }
     if (xml.error() && xml.error() != QXmlStreamReader::PrematureEndOfDocumentError) {
         qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString();
         http.abort();
     }
 }

这段代码看起来有点吓人,但这主要是因为它包含了几条嵌套的“if”语句,用于处理我们在RSS种子中将会遇到的不同类型的XML元素。

我们从依次读取每个元素开始,然后检查该元素在树上是属于新的内容项,一个元素的末端,还是包含真正的元素数据。

当代码检测到XML种子中一个新元素的起点时,它会将“currentTag”设为该元素中所包含数据的类型。我们只对“title”、“link”和“pubDate”字段感兴趣,而且当XML流移动到文件的字符部分时,每个字段的文本就会根据currentTag类型转移到“titleString”、“linkString”和“dateString”中。当检测到一个元素的终点时,我们已经知道这些字符串是否已经被填充,以及是否可以把数据复制到我们GUI中的“treeView”对象中。这就是“item->setText”行的作用,而这些字符串被添加到一个treeView顶部的内容项中,该treeView创建来保存“StartElement”部分中的每个RSS种子的树视图。

如果我们在理解这个函数时有困难,使用Creator的优秀调试器把代码完整地运行一遍,会对我们有所帮助。如果在这个函数中设置一个断点,当应用程序的执行到达代码的这个部分时,我们就能够使用Debug菜单单步调试每一行,并监视感兴趣参数的值。

最后,我们需要添加的最后一个函数是用于在用户点击RSS新闻项之一时,将该新闻项指向的web页面装载到我们的WebKit小部件中。这个函数是使用我们在GUI设计器中建立的“itemActivated” SIGNAL/SLOT连接来执行的。我们从树小部件内容项中找到了由信号传递的URL,并把这些数据发送给webView小部件,然后把它转换为一个QUrl,而我们也正是这样做的。幸运的是,此功能一共只需要两行代码:

 void MainWindow::itemActivated(QTreeWidgetItem * item)
 {
     ui->webView->load(QUrl(item->text(2)));
     ui->webView->show();
 
 }

d

* 尝试使用调试器来理解我们项目中一些更为复杂的函数。

运行应用程序

以上就是需要完成的全部工作。剩下的就是保存项目,编译和运行。点击“Add Feed”按钮可以添加我们在GUI中创建的默认RSS种子,而且我们应该看到,位于左侧的树视图使用了来自TuxRadar.com的所有最新内容进行填充。点击其中任意的内容,右侧的web查看器就会加载相应的页面。

但这个应用程序的最大优点是缩放两个面板的方式。在树视图和web页面之间,应该能够找到三个很小的垂直点。可以把这些点拖到左边或右边,从而改变RSS种子或正在显示的web页面的比例。如果将这一条完全移到右边,web视图就会完全关闭。如果我们只想看到种子列表,这是个不错的主意。

可以轻松给这个应用程序添加所需要的内容。我们从一个具有自动功能的刷新按钮开始。这个按钮功能是大约每小时增加一次新种子,或者在点击它时手动刷新。应用程序还迫切需要保存其设置的功能。这是一项十分艰巨的任务,几乎可以作为另一份指南的主题——为什么不亲自写写试试看呢?

e

完成之后的应用程序:密切注意Akregator,我们的RSS应用程序是跨平台的,而且使用WebKit来呈现web页面。

下载源代码:qt_mrss.tar

原文链接:http://www.tuxradar.com/content/code-project-create-qt-rss-reader
翻译CSDN:http://qt.csdn.net/articles.aspx?pointid=178

Noshow , , , ,

Qt 白皮书 (New)

2009年8月18日

中文版

-使用Qt Webkit集成创建混合应用 Qt_WebkitHybrid_whitepaper_cn

-使用Qt 和OpenGL®创建跨平台可视化UI Whitepaper_AdvancedVizUIwithQtOpenGL_cn

Qt, Technology , , , , , , ,

Qt 拥抱数字家庭

2009年8月5日

可能在大家通常的印象里,Qt是适合来开发桌面软件,如Google Earth,或者是作为诸如手机等嵌入式平台的中间件。但其实你可以在越来越多的数字家庭设备中看到Qt的身影里,这里面包括LCD TV,机顶盒,IPTV等等,比如已经上市的诸如Roku,或者以后大家可以见到的TCL,长虹,都会是基于Qt平台的。

其实对于Qt来说,数字家庭是一个很重要的平台,这也符合Qt Everywhere的远景。数字家庭,未来已经不仅局限于当前电视所提供的单一观看的功能,大家可以想象一下,当你的电视可以支持Widget,也就意味着你可以随时在查看天气信息,股票信息,也随时可以登陆Facebook,Twitter和你的朋友进行沟通,甚至还可以使用Skype和你的朋友进行对话,这才是未来电视的发展方向,大家可以看看Yahoo! TV的概念

那么为什么选用Qt作为数字家庭的平台呢,我想主要有三个原因:

阅读全文…

Qt , , , , , , ,

Qt 4.5 新功能逐一看 – WinCE 移植全部完成

2009年3月18日

大家可能知道,在Qt4.4版本发布的时候,就已经宣布了对Windows CE(Win Mobile)的官方支持。但其实在Qt4.4, WinCE版本的移植是基于桌面的Qt 4.3的,也又意味着有些遗留问题没有解决,其中最主要的两个一就是Webkit,另一个就是phonon。

所以现在在Qt4.5的WinCE版本中,就可以使用这两个功能了。Webkit自不必多说,但是需要注意的就是最好在WinCE 6的版本上使用,5就算了,原因如下:
“WINCE5.0只支持最多32并发进程(其中有4个要供自身调用),最大32MB的内存寻址。而在WINCE6.0中可支持到32000个并发进程,且每个进程最大2GB的寻址。”
而webkit对内存的要求是比较比较多的。好处就是,不用花钱买昂贵的Mobile Internet Explorer了。
另外一个功能就是phonon,Qt4.5里面提供了两个基于WinCE的Backend来支持phonon,一个是常用的Direct Show,另一个就是给低端设备提供的WaveOut。想多了解phonon的同学,可以猛击此处

话又说回来,为啥要用Windows CE呢?

Qt , , , , , , ,

Qt 4.5 新功能逐一看 – WebKit 集成

2009年3月16日

Qt 和 Webkit 的集成是在 Qt 4.4 的版本中实现的,关于什么是webkit,为什么要将 Qt 和 Webkit 集成在一起以及可以用来干什么等等内容,请移步此 在线研讨会
有空写写关于 Webkit,浏览器引擎的未来,周围也有很多朋友在积极的开发和贡献着。

今天主要介绍一下在 Qt 4.5 中 Webkit 集成的最新功能。

1. 首先是将 Webkit 升级到了最新的trunk版本。trunk 是目前 Webkit 最新的也是主要的开发分支,目前 Webkit 的 nightly build 就是基于 trunk 编译的。
trunk 的源代码在此:http://trac.webkit.org/browser/trunk
QtWebkit 现在已经是 trunk 中的一部分了,也就是说你也是直接在 Webkit 中使用 QtWebkit 代码,编译出 QtWebkit 库了。
相比与 Qt 4.4 中旧的 Webkit 核心,trunk 带来的好处包括:更好的网页兼容性,接近100%的 acid3 测试结果,不知道 acid3 的同学可以猛击此处,看看你的浏览器可以得几分?全屏幕缩放(包括字体以及图片,如果我没记错的话,这也是IE7的新功能),以及对CSS animation 和 transition 的支持,transition 其实就是最简单的 animation,目前来看,CSS animation 还是 Webkit 特有的扩展,想看看具体效果的同学可以分别在Safari 4 以及 Firefox 3中打开这个链接

2. 引入了对 Netscape plug-in 的支持,全称为:Netscape Plugin Application Programming Interface (NPAPI), Netscape Navigator 浏览器早已离我们远去,但Netscape plug-in 却还顽强的活着,并且成为绝大多数浏览器都支持的跨平台插件标准,其中最常见的N插件莫过于 Flash 了,想想满世界的类 “Youtube” 你就知道了。 现在 Qt 4.5 中支持了N插件,最直观的改变就是在 Qt Demo Browser 中原本应该显示 Flash 的位置不会再是一片空白了。
还能做什么? 一个 Youtube 的客户端应该很容易。

3. HTML 5! 这个最最最新的 Html 规范,估计还没有几个人真正用上。唯一见到的应用(也是预览)就是, Google 在 Android 平台的 HTC Magic 和 Mac OS 的 iphone 3g 上演示了基于 HTML5 的离线 Gmail。当然,HTML5还引入一些其他新的元素,诸如 audio 和 video。 不过联想到 Qt 里面的 Phonon 和 sqlite 模块,你就应该能理解 Qt 对于 HTML5 的支持应该就是水到渠成了吧。
关于HTML5的文章,请移步
关于 Gmail 在不同设备的演示,请移步

4. SquirrelFish Javascript 引擎。先来个 logo
squirrelfish
SquirrelFish 是全新的 javascript 引擎,相比于原来 Webkit 中的 JavaScriptCore, 特点就是一个“快”!下面这张图是 SquirrelFish 和原来 Webkit JavaScriptCore 运行 SunSpider 测试的性能对比,Longer bars are better.
squirrelfish-webkit-graph
现在浏览器星球 javascript 引擎众多,有空抄一些东西写篇纵览。

最后来张ppt:
webkitintegration

先到这吧。

Qt , , , , , , , , ,