基于QtWebkit的嵌入式bs架构设计
2019-07-13 00:48发布
生成海报
基于
QtWebkit
的嵌入式
bs
架构设计
Write
by
:
tadaya
概述:本文旨在介绍如何使用
QtWebkit
来实现嵌入式客户端(
browser
),而不关注
webkit
引擎的原理和任何效率问题。重点关注如何使用遥控器去操作网页中的元素(例如焦点移动,打开新的链接),这种应用在目前的
iptv
上应用非常广泛,通过实现自己的
browser
,可以加载不同的风格的界面(即网页),结合使用
qt
其他控件和
QtWebkit
(框架)实现功能与界面完美结合的产品。
关键字:焦点,
QtWebkit
,元素
一.嵌入式
BS
架构的优势。
嵌入式
bs
架构的设计与
pc
上的
bs
架构的区别:
1.pc
上无须自行设计浏览器,嵌入式需要对浏览器进行特殊处理。(如按键等)
2.
嵌入式需要加上对遥控器的支持。(如
tv
遥控器)
3.pc
上支持的网页元素比嵌入式要多。
4.
嵌入式需要做多套网页以适应不同屏幕的分辨率。
5.
嵌入式需要考虑
page cache
和
flash
权衡的问题。
bs
架构比
cs
架构的优势:
1.
设计简单。大部分界面和部分功能都在后台服务器实现。
2.
界面炫丽。使用网页可以达到很炫的效果,显示格式也非常好控制。
3.
修改方便。基本上只需修改网页就可以了。
4.
可扩展性强。一个设计好的
browser
可以使用不同风格的网页,如:加载
youku
看电影,加载土豆看电影(不过这比较困难,焦点通过遥控器的移动在网页中链接,输入框,
button
之间是一个非常困难的过程,嵌入式
flash player
很少)。
二.
QtWebkit
的优势以及使用
QtWebkit
只是一个浏览器框架,其核心引擎时
webkit
,
QtWebkit
简单的归纳为
webkit
的显示界面,即表现层和逻辑层的关系。
QtWebkit
的优势在于:
1.
可移植性强。
Linux
,
windows
,
embedded linux
。
2.
对
javascript
支持比较好。
3.
对
css
支持比较全面。
4.
封装比较好,简单易用。
需要用到
QtWebkit
时,需要在编译
QT
源码的时候,在
./configure
加上
–webkit
,在编译自己的应用程序时,需要在
.pro
文件加上
QT+=webkit
,或者直接改
Makefile
加上
-lQWebkit
,简单的
browser
程序如下:
int
main(int argc, char* argv[])
{
QApplication app(argc,argv);
QWebview
*view = new QWebview ();
view->setGeometry(0,0,1024,1000);
view->load(QUrl("www.baidu.com"));
view->show();
return app.exec();
}
3.
通过键盘(遥控器)控制网页元素
通过使用
QWebview
,
QWebFrame
,
QWebPage
类就基本上可以实现浏览器的所有功能,而我们重点关注是
QWebElement
这个类,该类封装了网页中
element
,即每个
就是一个
QWebElement
对象,不仅仅局限于
,,
等等都是一个
QWebElement
,而我们要通过遥控控制焦点的移动就需要调用
element.focus()(
注:
qt 4.6
以后才有这个方法
)
。
举例说明:
需求
:
通过上下左右键来移动
baidu
中链接(即
元素),并改变相应链接的颜 {MOD}。
实现分析:利用
QWebview
加载
baidu
,然后将
标签全部提取出来,放在
QWebElement list
中,(注:需要加载网页成功后才开始提取,否则会出现提取不到。即当
emit
signal loadFinished(bool)
后才开始提取)。重写
QWebview
的
keyPressEvent
函数,
QWebview
默认的上下左右键是当网页显示不下时滚动的处理,这点可通过源码以及默认的处理看出来,但可以通过
tab
键实现焦点移动,当收到上下左右键时可通过把按键事件改为
Qt
::
Key_Tab
键事件来实现焦点移动(示例程序不是通过这种方法)。
改变相应链接的颜 {MOD}有很多方法,暂列举
2
种:
1.
当焦点挪动时恢复原聚焦的元素的
style
,给现聚焦的元素加上新的
style
。
2.
自写一个通明控件,当焦点聚焦时将改空间放在元素对应的位置。
代码:
#include "browser.h"
#include
browser::browser(QWidget * parent/* = 0
*/):QWebView(parent)
{
focusIndex = 0;
frame=this->page()->currentFrame();
frame->setScrollBarPolicy(Qt::Horizontal ,Qt::ScrollBarAlwaysOff);
frame->setScrollBarPolicy(Qt::Vertical ,Qt::ScrollBarAlwaysOff);
connect(this,SIGNAL(loadFinished(bool)),this,SLOT(loadPageFinish(bool)));
/* set webview no transparent */
QPalette
palette(QColor(255,0,0));
this->setPalette(palette);
this->setAttribute(Qt::WA_OpaquePaintEvent,
false);
}
browser::~browser()
{
}
QString ed = "";
void browser::loadPageFinish(bool finish)
{
if (finish)
{
focusIndex = 0;
QWebFrame
*frame=this->page()->currentFrame();
QWebElement
document=frame->documentElement();
//printf("%s%s/n",ed.toLocal8Bit().data(),document.tagName().toLocal8Bit().data());
//examineChildElements(document);
elementList.clear();
elementList = document.findAll("a").toList();
if (elementList.size() > focusIndex)
{
QWebElement element;
element = elementList.at(focusIndex);
if (element.hasAttribute("style"))
{
preFocusStyle =
element.attribute("style","");
}
element.setFocus();
element.setAttribute("style", "background-color:
#ff0000");
}
}
/*
set page transparent,so we can see view's background*/
QPalette palette = this->palette();
palette.setBrush(QPalette::Base,
Qt::transparent);
this->page()->setPalette(palette);
}
void browser::examineChildElements(const
QWebElement &parentElement)
{
ed += "
";
QWebElement element = parentElement.firstChild();
while (!element.isNull())
{
printf("%s%s/n",ed.toLocal8Bit().data(),element.tagName().toLocal8Bit().data());
if (element.hasFocus())
{
qDebug()<";
}
if (element.toPlainText() == QString("hao123"))
{
element.setAttribute("style", "background-color:
#ff0000");
element.setFocus();
};
examineChildElements(element);
if (ed.length()> 2)
{
ed.remove(0,2);
}
element = element.nextSibling();
}
}
void browser::keyPressEvent(QKeyEvent * ev)
{
switch (ev->key())
{
case Qt::Key_Right:
case Qt::Key_Left:
{
if (elementList.size() > focusIndex)
{
QWebElement element =
elementList.at(focusIndex);
if (!element.isNull())
{
if
(element.hasAttribute("style"))
{
element.setAttribute("style",
preFocusStyle);
}
focusIndex += 1;
if (elementList.size() ==
focusIndex)
focusIndex = 0;
element = elementList.at(focusIndex);
if
(element.hasAttribute("style"))
{
preFocusStyle =
element.attribute("style","");
}
element.setFocus();
element.setAttribute("style",
"background-color: #ff0000");
//
QLabel* label = new
QLabel(this);
//
label->setGeometry(element.geometry());
//
label->setText("i
am focus");
//
label->show();
//
label->raise();
}
}
}
break;
default:
QWebView::keyPressEvent(ev);
}
}
程序效果图(一)
程序效果图(二)
运行效果图说明:
1.
初始焦点在“登录”(第一个链接)
2.
移动后新焦点被我们设置
style
为红 {MOD}。
3.
QWebView
默认的
enter
键会打开链接地址。
总结:上述程序只能左移到上一个链接或者右移到下一个链接,这种控制焦点的方式在简单的几个链接的网页比较合适,在需要精确的控制焦点移动时,最好通过网页本身去做(如调用
js
脚本等),
QWebview
调用
js
脚本以及与
js
通信的示例资料网上很多,这里不做陈述。
该示例程序重点旨在介绍焦点在网页如何移动,这对做无鼠标嵌入式开发人员来说比较重要,
enjoy it
!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮