找回密码
 立即注册
收起左侧

第40篇 网络(十)WebKit初识

48
回复
36671
查看
[复制链接]
累计签到:1564 天
连续签到:1 天
来源: 2013-9-11 17:26:05 显示全部楼层 |阅读模式
WebKit初识

版权声明

该文章原创于Qter开源社区(www.qter.org),作者yafeilinux,转载请注明出处!


导语


WebKit是一个开源的浏览器引擎。Qt中提供了基于WebKit的QtWebKit模块,它包含了一组相关的类。QtWebKit提供了一个Web浏览器引擎,使用它便可以很容易的将万维网(WorldWide Web)中的内容嵌入到Qt应用程序中。与此同时,本地也可以对Web内容进行控制。QtWebKit可以呈现HTML(HyperTextMarkup Language,超文本标记语言)文档、XHTML(Extensible HyperTextMarkup Language,可扩展超文本标记语言)文档和SVG(Scalable VectorGraphics,可缩放矢量图形)文档,风格使用CSS(Cascading StyleSheets,层叠样式表),脚本使用JavaScript。在JavaScript执行环境和Qt对象模型间搭建的桥梁,实现了使用WebKit的JavaScript环境访问本地对象。关于这一点,大家可以在帮助中参考The QtWebKit Bridge关键字对应的文档。通过整合Qt的网络模块,实现了从Web服务器、本地文件系统甚至Qt资源系统中透明的加载Web页面。





环境:Windows Xp + Qt 4.8.5+Qt Creator2.8.0




目录


一、简单应用
二、扩展应用




正文


一、简单应用


下面我们来实现一个可以打开特定网页的程序。新建空的Qt项目,在pro项目文件中添加一行代码:QT += webkit,然后向项目中添加一个main.cpp文件,并在其中添加如下代码:
#include <QWebView>
#include <QApplication>
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    QWebView view;
    view.load(QUrl("http://www.qter.org"));
    view.show();
    return a.exec();
}


       要使用WebKit,就要先添加webkit模块。QWebViewQtWebKit模块主要的窗体部件,它可以在各种应用程序中用来显示Internet上的网页内容。QWebView作为一个窗口部件,可以嵌入到窗体或者图形视图部件中。


QWebView用来显示Web页面,每个QWebView实例都包含一个QWebPage对象。QWebPage提供了对一个页面的文档结构的访问,描述了如框架(frame)、访问历史记录和可编辑内容的撤销/重做栈等特色。每一个QWebPage都包含一个QWebFrame对象作为它的主框架。在HTML中的每一个单独的框架都可以使用QWebFrame来表示,这个类包含了到JavaScript窗口对象的桥梁,而且可以进行绘制。在QWebPage的主框架中可以包含很多的子框架。


HTML文档中单独的元素可以通过DOM JavaScript接口进行访问,在QtWebKit中与这个接口等价的接口由QWebElement来表示。QWebElement对象可以使用QWebFrame的findAllElement()和findFirstElement()函数来获取。一般的网页浏览器的特色设置都可以通过QWebSettings类来配置,可以通过默认设置为所有的QWebPage实例提供默认值。单独的属性可以使用页面指定的设置对象进行重写。



二、扩展应用


下面再来看一个可以随意更改网址并且可以显示网站logo的例子。新建Qt Gui应用,项目名称为“webview”,类名和基类保持“MainWindow”和“QMainWindow”不变。完成后向webview.pro文件中添加QT += webkit一行代码,并按下Ctrl + S保存该文件。



1.下面到mainwindow.h文件中,先添加头文件:
#include <QWebView>
#include <QLineEdit>
然后添加槽的声明:
protected slots:
    void changeLocation();     // 改变路径
    void setProgress(int);     // 更新进度
    void adjustTitle();        // 更新标题显示
void finishLoading(bool);  // 加载完成后进行处理
       再添加对象和变量定义:
QWebView *view;
QLineEdit *locationEdit;
int progress;



2.下面到mainwindow.cpp文件中,在构造函数中添加如下代码:
  1. progress = 0;
  2. view = new QWebView(this);
  3. setCentralWidget(view);
  4. resize(800, 600);

  5. // 关联信号和槽
  6. connect(view, SIGNAL(loadProgress(int)), this, SLOT(setProgress(int)));
  7. connect(view, SIGNAL(titleChanged(QString)), this, SLOT(adjustTitle()));
  8. connect(view, SIGNAL(loadFinished(bool)), this, SLOT(finishLoading(bool)));
  9. locationEdit = new QLineEdit(this);
  10. connect(locationEdit, SIGNAL(returnPressed()), this, SLOT(changeLocation()));

  11. // 向工具栏添加动作和部件
  12. ui->mainToolBar->addAction(view->pageAction(QWebPage::Back));
  13. ui->mainToolBar->addAction(view->pageAction(QWebPage::Forward));
  14. ui->mainToolBar->addAction(view->pageAction(QWebPage::Reload));
  15. ui->mainToolBar->addAction(view->pageAction(QWebPage::Stop));
  16. ui->mainToolBar->addWidget(locationEdit);

  17. // 设置并加载初始网页地址
  18. locationEdit->setText("http://www.baidu.com");
  19. view->load(QUrl("http://www.baidu.com"));
复制代码
       QWebView开始加载时,会发射loadStarted()信号;而每当一个网页元素(例如一张图片或一个脚本等)加载完成时,都会发射loadProgress()信号;最后,当加载全部完成后,会发射loadFinished()信号,如果加载成功,该函数的参数为true,否则为false。可以使用title()来获取HTML文档的标题,如果标题发生了改变,将会发射titleChanged()信号。



3.下面添加那几个槽的定义:
void MainWindow::changeLocation()
{
    QUrl url = QUrl(locationEdit->text());
    view->load(url);
    view->setFocus();
}
void MainWindow::setProgress(int p)
{
    progress = p;
    adjustTitle();
}
void MainWindow::adjustTitle()
{
    if ( progress <= 0 || progress >= 100) {
       setWindowTitle(view->title());
    } else {
setWindowTitle(QString("%1 (%2%)").arg(view->title()).arg(progress));
    }
}
void MainWindow::finishLoading(bool finished)
{
    if (finished) {
       progress = 100;
       setWindowTitle(view->title());
    } else {
       setWindowTitle("web page loading error!");
    }
}


       下面运行程序,效果如下图所示:






结语



WebKit是一个很庞大的体系,我们这里只是讲解了其最基本的应用,有兴趣的朋友可以结合Qt文档来进一步的学习。




涉及到的代码:





上一篇:    第39篇 网络(九)进程和线程

下一篇:   

返回:系列教程目录    



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

累计签到:894 天
连续签到:1 天
2013-9-13 19:20:47 显示全部楼层
请教一个问题,我写的一个网页浏览器,在我的电脑上运行正常,
但是到虚拟机(xp sp3)能运行,但是图片显示不出来,如下图,请问这是怎么回事。


回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2013-9-16 13:55:52 显示全部楼层
Syylc120317 发表于 2013-9-13 19:20
请教一个问题,我写的一个网页浏览器,在我的电脑上运行正常,
但是到虚拟机(xp sp3)能运行,但是图片显 ...

看不到图啊。可能是虚拟机的问题,可以在其他机子上试试。
回复 支持 反对

使用道具 举报

累计签到:894 天
连续签到:1 天
2013-9-16 19:54:03 显示全部楼层
yafeilinux 发表于 2013-9-16 13:55
看不到图啊。可能是虚拟机的问题,可以在其他机子上试试。

这个问题解决了,后来是把imageformats文件夹的gif和jpeg的dll文件复制过去就行了。默认支持png的,所以有的gif和jpeg格式的显示不出来。
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2013-9-17 14:53:16 显示全部楼层
Syylc120317 发表于 2013-9-16 19:54
这个问题解决了,后来是把imageformats文件夹的gif和jpeg的dll文件复制过去就行了。默认支持png的,所以 ...

嗯。如果用到其他模块,在发布的时候是需要复制相关文件的。
回复 支持 反对

使用道具 举报

尚未签到

2013-10-30 13:30:28 显示全部楼层
你好,我在win7下运行程序(qt-windows-opensource-5.1.1-mingw48_opengl-x86-offline),当打开网址http://auto.news18a.com时,程序提示已停止工作。
Error - RtlWerpReportException failed with status code :-1073741823. Will try to launch the process directly
问题事件名称:        APPCRASH
  应用程序名:        mybrowser.exe
  应用程序版本:        0.0.0.0
  应用程序时间戳:        52709589
  故障模块名称:        Qt5WebKitd.dll
  故障模块版本:        5.1.1.0
  故障模块时间戳:        521a74be
  异常代码:        c0000005
  异常偏移:        001e06ad
  OS 版本:        6.1.7600.2.0.0.256.1
  区域设置 ID:        2052
  其他信息 1:        0a9e
  其他信息 2:        0a9e372d3b4ad19135b953a78882e789
  其他信息 3:        0a9e
  其他信息 4:        0a9e372d3b4ad19135b953a78882e789
调试时,提示“底层由于接受到操作系统的信号而停止。信号名称:SIGSEGV,信号含义:Segmentation fault.
问题出在哪?
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2013-10-30 16:46:35 显示全部楼层
qidai2010 发表于 2013-10-30 13:30
你好,我在win7下运行程序(qt-windows-opensource-5.1.1-mingw48_opengl-x86-offline),当打开网址http:/ ...

出现这个问题一般是因为程序中出现了致命错误。

可以通过调试看看是哪里的问题,打开别的网页没有问题吧?
回复 支持 反对

使用道具 举报

尚未签到

2013-10-30 17:33:46 显示全部楼层
yafeilinux 发表于 2013-10-30 16:46
出现这个问题一般是因为程序中出现了致命错误。

可以通过调试看看是哪里的问题,打开别的网页没有问题吧 ...

调试的时候没发现有黄色箭头出现。
这个公司的大多数网页都打不开,但是百度那些的都没有问题。
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2013-10-30 19:34:24 显示全部楼层
qidai2010 发表于 2013-10-30 17:33
调试的时候没发现有黄色箭头出现。
这个公司的大多数网页都打不开,但是百度那些的都没有问题。 ...

那应该是这个网站得构架或者其中的代码有特殊设置吧。
回复 支持 反对

使用道具 举报

尚未签到

2013-10-31 16:26:08 显示全部楼层
请问有什么方法可以实现QT程序与浏览器通讯(比如知道网页加载完成)的方法吗?
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2013-10-31 17:01:35 显示全部楼层
qidai2010 发表于 2013-10-31 16:26
请问有什么方法可以实现QT程序与浏览器通讯(比如知道网页加载完成)的方法吗? ...

嗯,如果是自己使用webkit创建的浏览器,比较容易实现。

如果是外部浏览器的话,需要看该浏览器是否提供相应信息。
回复 支持 反对

使用道具 举报

累计签到:14 天
连续签到:1 天
2013-12-9 18:15:04 显示全部楼层
能不能写一个,加载本地网页的例子啊。
回复 支持 反对

使用道具 举报

累计签到:2 天
连续签到:1 天
2013-12-9 19:06:43 显示全部楼层
版主!请问目前的QtWebkit模块支持静态编译吗?如果不可以,那有其他方式将QtWebkit模块静态加载到程序中?
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2013-12-9 20:37:41 显示全部楼层
cwzQter 发表于 2013-12-9 19:06
版主!请问目前的QtWebkit模块支持静态编译吗?如果不可以,那有其他方式将QtWebkit模块静态加载到程序中? ...

可不可以静态编译,这个倒没试过。

不过,一般不建议静态编译的,因为后续程序更新会很困难。
回复 支持 反对

使用道具 举报

累计签到:2 天
连续签到:1 天
2013-12-13 11:29:27 显示全部楼层
yafeilinux 发表于 2013-12-9 20:37
可不可以静态编译,这个倒没试过。

不过,一般不建议静态编译的,因为后续程序更新会很困难。 ...

谢及时坛主回复!我会采纳你的建议的
回复 支持 反对

使用道具 举报

累计签到:4 天
连续签到:1 天
2014-2-9 11:18:29 显示全部楼层
yafei老师
       新年好,想请教一个问题:浏览器中像火狐中那种可以同时打开多个网页窗口的浏览器怎么实现?
       另外我想开发的浏览器提一些建议和思路吗? 谢谢!

回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2014-2-10 10:41:44 显示全部楼层
ktz 发表于 2014-2-9 11:18
yafei老师
       新年好,想请教一个问题:浏览器中像火狐中那种可以同时打开多个网页窗口的浏览器怎么实 ...

可以尝试使用多窗口部件QMdiArea试试。

其实写个简单的浏览器显示数据是可以的,如果想做大,这个有点难,就像那些大公司做的浏览器,感觉也一般,但是投资上亿都是正常的。

在Qt提供的例子里面有个 Browser 的演示程序,这是个开源浏览器,可以参考下它的代码。
回复 支持 反对

使用道具 举报

累计签到:3 天
连续签到:1 天
2014-8-22 09:28:38 显示全部楼层
版主,运行出现错误QWebview no such file or directory是什么原因,用的是QT4.8
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2014-8-27 21:23:39 显示全部楼层
Shaun 发表于 2014-8-22 09:28
版主,运行出现错误QWebview no such file or directory是什么原因,用的是QT4.8

在项目文件中添加Qt += webkit

然后添加头文件#include<QtWebKit>
回复 支持 反对

使用道具 举报

累计签到:5 天
连续签到:1 天
2014-9-12 12:58:54 显示全部楼层
如果要打开多个页面,要怎么实现呢?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了