博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用QtWebKit开发简单的浏览器
阅读量:6587 次
发布时间:2019-06-24

本文共 5179 字,大约阅读时间需要 17 分钟。

用QtWebKit开发简单的浏览器

 

1.代码实现
工程目录结构如下:
AddressBar类包含了地址栏和按钮两个控件,将地址栏回车和按钮点击信号与goToSite()槽连接。
当回车和点击事件发生时,goToSite()将获得Url地址并发送go(QUrl)信号。
addressbar.h
#ifndef ADDRESSBAR_H#define ADDRESSBAR_H#include 
#include
#include
#include
#include
#include
class AddressBar : public QWidget { Q_OBJECT public: explicit AddressBar(QWidget *parent = 0); signals: void go(QUrl); public slots: void goToSite(); private: QLineEdit *addressEdit; QPushButton *goButton; QHBoxLayout *layout; }; #endif // ADDRESSBAR_H
addressbar.cpp
#include "addressbar.h"AddressBar::AddressBar(QWidget *parent) :    QWidget(parent){    addressEdit = new QLineEdit(parent);    goButton = new QPushButton("Go", parent);    layout = new QHBoxLayout;    layout->addWidget(addressEdit);    layout->addWidget(goButton);    this->setLayout(layout);    connect(goButton, SIGNAL(clicked()), this, SLOT(goToSite()));    connect(addressEdit, SIGNAL(returnPressed()), this, SLOT(goToSite()));}void AddressBar::goToSite(){    QString address = addressEdit->text();    emit go(QUrl(address));}
接下来是QtWebkit包中的主要类QWebView,我们借助这个类来渲染Url指向的网页。
为了当用户在地址栏回车或者点击Go按钮时能够自动加载网页,我们需要给QWebView
添加loadNewPage(QUrl)槽(因为QWebView没有类似load(QUrl)的槽),并将其与go(QUrl)
信号连接。所以我们实现一个QWebView的子类HtmlView。
htmlview.h
#ifndef HTMLVIEW_H#define HTMLVIEW_H#include 
class HtmlView : public QWebView { Q_OBJECT public: explicit HtmlView(QWidget *parent = 0); signals: public slots: void loadNewPage(const QUrl &url); }; #endif // HTMLVIEW_H
htmlview.cpp
#include "htmlview.h"HtmlView::HtmlView(QWidget *parent) :    QWebView(parent){}void HtmlView::loadNewPage(const QUrl &url){    this->load(url); }
接下来实现程序的主窗口QMainWindow,将AddressBar和HtmlView放置其中。
mainwindow.h
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include 
#include
#include
#include
#include
#include
#include "addressbar.h" #include "htmlview.h" class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :    QMainWindow(parent){    // 1.Create widget    QWidget *centralWidget = new QWidget(this); AddressBar *bar = new AddressBar; HtmlView *view = new HtmlView; // 2.Add widget to layout QGridLayout *layout = new QGridLayout; layout->addWidget(bar, 0, 0, 1, 10); layout->addWidget(view, 1, 0, 1, 10); centralWidget->setLayout(layout); // 3.Connect widget QObject::connect(bar, SIGNAL(go(QUrl)), view, SLOT(loadNewPage(QUrl))); this->setCentralWidget(centralWidget); this->setWindowTitle("My Browser v1.0"); this->resize(640, 480); }
最后是程序的入口main.cpp
#include 
#include "mainwindow.h"int main(int argc, char *argv[]){ QApplication app(argc, argv); MainWindow *window = new MainWindow; window->show(); return app.exec(); }
2.事件流分析
我们分别为AddressBar和HtmlView自定义了两个槽goToSite(QUrl)和loadNewPage(QUrl),以及新的信号go(QUrl)。
就是为了将Url地址传递给QWebView的load函数。
这里需要注意的是SIGNAL-SLOT机制是Qt的内部机制,它是同步执行的。源头上returnPressed()和clicked()槽的触发,
是从操作系统的事件队列中得到的,并进行异步的处理。以QPushButton的clicked()槽的触发为例,QApplication.exec()
执行后将会监听操作系统事件队列,当鼠标事件发生时,事件将会发送到QPushButton的event()函数进行分发:
QPushButton::event -> QAbstractButton::event ->QWidget::event [Dispatch event]:    case QEvent::KeyPress: {        QKeyEvent *k = (QKeyEvent *)event; bool res = false; if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier? if (k->key() == Qt::Key_Backtab || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) res = focusNextPrevChild(false); else if (k->key() == Qt::Key_Tab) res = focusNextPrevChild(true); if (res) break; } keyPressEvent(k); -> QPushButton::keyPressEvent void QPushButton::keyPressEvent(QKeyEvent *e) { Q_D(QPushButton); switch (e->key()) { case Qt::Key_Enter: case Qt::Key_Return: if (autoDefault() || d->defaultButton) { click(); break; } // fall through default: QAbstractButton::keyPressEvent(e); } } -> QAbstractButton::click: void QAbstractButton::click() { if (!isEnabled()) return; Q_D(QAbstractButton); QPointer
guard(this); d->down = true; d->emitPressed(); if (guard) { d->down = false; nextCheckState(); if (guard) d->emitReleased(); if (guard) d->emitClicked(); } }
3.SIGNAL-SLOT类的编译
关于Q_OBJECT宏以及SIGNAL,SLOT,emit等关键字奇怪的语法,其实他们是通过一个叫做MOC元对象编译器
的组件来进行预编译的,因此我们可以使用SIGNAL,SLOT,emit来清晰地连接各个信号槽,而非函数指针。
SIGNAL-SLOT使用很方便,但也是会损失一点执行效率,使用时要谨慎。
4.总结及学习资料
通过这个例子可以对Qt的SIGNAL-SLOT机制有个简单的了解,它可以减少对象间的依赖。假如不使用它,我们就
需要在AddressBar中直接调用HtmlView的load()函数,两个类耦合在了一起。在这个例子中MainWindow负责AddressBar
和HtmlView的构建和连接,使它们互相不知道对方的存在!
让我更感兴趣的其实是QtWebKit,通过它我们可以在Qt开发桌面应用时使用Web技术,而不用局限于Qt,MFC等等。
Web开发人员也可以投身桌面应用开发之中。
QtWebKit官方文档:http://doc.qt.nokia.com/4.7-snapshot/qtwebkit.html
学习笔记:http://caterpillar.onlyfun.net/Gossip/Qt4Gossip/Qt4Gossip.html
QtWebKit系列教程:http://software.intel.com/zh-cn/blogs/2010/06/08/qt-webkit-qt-webkit/
信号槽深入学习:http://www.ibm.com/developerworks/cn/linux/guitoolkit/qt/signal-slot/

QtWeb - 一个开源的Qt浏览器项目

转载地址:http://llhno.baihongyu.com/

你可能感兴趣的文章
如何真正学好数据科学?
查看>>
数据中心那些常见的问题
查看>>
在Linux中如何使用gdb调试C程序
查看>>
智能交通助力城市道路行车提速15%
查看>>
PRICAI 2016 论文精选 | 基于车辆优先级优化交通系统的道路分布
查看>>
沃兹批评苹果避税:纳税还不如我积极
查看>>
《HTML5 Canvas游戏开发实战》——3.3 自定义画板
查看>>
物联网平台之争 巨头竞合并存
查看>>
6个用好大数据的秘诀
查看>>
五年50起并购、股价持续上扬,复盘IBM的物联网进化之路
查看>>
罗曼股份抢先驶入四万亿智慧城市建设主航道
查看>>
Gartner:2015年启动的企业级区块链项目90%会失败,它们犯了这十大常见错误
查看>>
企业微信正式发布 与阿里“钉钉”共逐移动办公市场
查看>>
行存、列存,堆表、AO表性能对比 - 阿里云HDB for PostgreSQL最佳实践
查看>>
机构报告:大数据分析提升企业决策水平
查看>>
有好事?卡巴斯基推出免费杀毒软件
查看>>
老旧小区安防升级改造有机遇也有难度
查看>>
HTML5标准有缺陷 手机电池信息可泄露上网活动
查看>>
网秦任命两位新董事 成立投资委员会
查看>>
《Oracle高性能SQL引擎剖析:SQL优化与调优机制详解》一第一篇 执行计划
查看>>