PyQt写的浏览单web页面的browser - 代码分享 - 开源中国社区
巫云
PyQt写的浏览单web页面的browser
巫云 发布于 2011年06月13日 16时, 6评/2080阅
分享到
新浪微博腾讯微博
收藏+7
踩 顶 0
借鉴别人代码修改的,模拟了简单的浏览器原理
共同学习,共同进步。
标签: QT Python Web PyQt
代码片段(3)
[代码] 程序代码
view source
print?
001 #!/usr/bin/env python
002
003 import sys
004
005 from PyQt4 import QtCore, QtGui
006 from browser import Ui_HttpWidget
007
008 class httpWidget(QtGui.QWidget):
009 def __init__(self, parent=None):
010 super(httpWidget, self).__init__(parent)
011 self.ui = Ui_HttpWidget()
012 self.ui.setupUi(self)
013
014 L = self.layout()
015 L.setMargin(0)
016 self.ui.horizontalLayout.setMargin(5)
017
018 url = 'http://google.com'
019 self.ui.url.setText(url)
020
021 self.ui.webView.setUrl(QtCore.QUrl(url))
022
023 self.ui.back.setEnabled(False)
024 self.ui.next.setEnabled(False)
025
026 QtCore.QObject.connect(self.ui.back, QtCore.SIGNAL("clicked()"),\
027 self.back)
028 QtCore.QObject.connect(self.ui.next, QtCore.SIGNAL("clicked()"),\
029 self.next)
030 QtCore.QObject.connect(self.ui.url, QtCore.SIGNAL("returnPressed()"),\
031 self.url_changed)
032 QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("linkClicked(const QUrl&)"),\
033 self.link_clicked)
034 QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("urlChanged(const QUrl&)"),\
035 self.link_clicked)
036 QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("loadProgress(int)"),\
037 self.load_progress)
038 QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("titleChanged(const QString&)"),\
039 self.title_changed)
040 QtCore.QObject.connect(self.ui.reload, QtCore.SIGNAL("clicked()"),\
041 self.reload_page)
042 QtCore.QObject.connect(self.ui.stop, QtCore.SIGNAL("clicked()"),\
043 self.stop_page)
044
045 QtCore.QMetaObject.connectSlotsByName(self)
046
047 def url_changed(self):
048 page = self.ui.webView.page()
049 history = page.history()
050 if history.canGoBack():
051 self.ui.back.setEnabled(True)
052 else:
053 self.ui.back.setEnabled(False)
054
055 if history.canGoForward():
056 self.ui.next.setEnabled(True)
057 else:
058 self.ui.next.setEnabled(False)
059
060 url = self.ui.url.text()
061 self.ui.webView.setUrl(QtCore.QUrl(url))
062
063 def stop_page(self):
064 self.ui.webView.stop()
065
066 def title_changed(self, title):
067 self.setWindowTitle(title)
068
069 def reload_page(self):
070 self.ui.webView.setUrl(QtCore.QUrl(self.ui.url.text()))
071
072 def link_clicked(self, url):
073 page = self.ui.webView.page()
074 self.__setHistButtonState(page, self.ui.back, self.ui.next)
075
076 self.ui.url.setText(url.toString())
077
078 def load_progress(self, load):
079 if load == 100:
080 self.ui.stop.setEnabled(False)
081 else:
082 self.ui.stop.setEnabled(True)
083
084 def back(self):
085 page = self.ui.webView.page()
086 self.__setHistButtonState(page, self.ui.back, None)
087 history = page.history()
088 history.back()
089
090 def next(self):
091 page = self.ui.webView.page()
092 history = page.history()
093 history.forward()
094
095 self.__setHistButtonState(page, None, self.ui.next)
096
097 #control the navigator buttons enability
098 def __setHistButtonState(self, page, back, next):
099 history = page.history()
100
101 if back is not None:
102 if history.canGoBack():
103 back.setEnabled(True)
104 else:
105 back.setEnabled(False)
106
107 if next is not None:
108 if history.canGoForward():
109 next.setEnabled(True)
110 else:
111 next.setEnabled(False)
112
113
114 if __name__ == "__main__":
115 app = QtGui.QApplication(sys.argv)
116 myapp = httpWidget()
117 myapp.show()
118 sys.exit(app.exec_())
119
120
121
122
[代码] QtDesigner生成的界面代码
view source
print?
01 # -*- coding: utf-8 -*-
02
03 # Form implementation generated from reading ui file 'httpWidget.ui'
04 #
05 # Created: Mon Jun 13 15:26:37 2011
06 # by: PyQt4 UI code generator 4.8.4
07 #
08 # WARNING! All changes made in this file will be lost!
09
10 from PyQt4 import QtCore, QtGui
11
12 try:
13 _fromUtf8 = QtCore.QString.fromUtf8
14 except AttributeError:
15 _fromUtf8 = lambda s: s
16
17 class Ui_HttpWidget(object):
18 def setupUi(self, HttpWidget):
19 HttpWidget.setObjectName(_fromUtf8("HttpWidget"))
20 HttpWidget.resize(636, 336)
21 self.verticalLayout = QtGui.QVBoxLayout(HttpWidget)
22 self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
23 self.horizontalLayout = QtGui.QHBoxLayout()
24 self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
25 self.back = QtGui.QPushButton(HttpWidget)
26 icon = QtGui.QIcon()
27 icon.addPixmap(QtGui.QPixmap(_fromUtf8("back.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
28 self.back.setIcon(icon)
29 self.back.setObjectName(_fromUtf8("back"))
30 self.horizontalLayout.addWidget(self.back)
31 self.next = QtGui.QPushButton(HttpWidget)
32 self.next.setEnabled(True)
33 self.next.setLayoutDirection(QtCore.Qt.RightToLeft)
34 icon1 = QtGui.QIcon()
35 icon1.addPixmap(QtGui.QPixmap(_fromUtf8("next.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
36 self.next.setIcon(icon1)
37 self.next.setObjectName(_fromUtf8("next"))
38 self.horizontalLayout.addWidget(self.next)
39 self.stop = QtGui.QPushButton(HttpWidget)
40 icon2 = QtGui.QIcon()
41 icon2.addPixmap(QtGui.QPixmap(_fromUtf8("stop.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
42 self.stop.setIcon(icon2)
43 self.stop.setObjectName(_fromUtf8("stop"))
44 self.horizontalLayout.addWidget(self.stop)
45 self.reload = QtGui.QPushButton(HttpWidget)
46 icon3 = QtGui.QIcon()
47 icon3.addPixmap(QtGui.QPixmap(_fromUtf8("reload.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
48 self.reload.setIcon(icon3)
49 self.reload.setObjectName(_fromUtf8("reload"))
50 self.horizontalLayout.addWidget(self.reload)
51 self.url = QtGui.QLineEdit(HttpWidget)
52 self.url.setObjectName(_fromUtf8("url"))
53 self.horizontalLayout.addWidget(self.url)
54 self.verticalLayout.addLayout(self.horizontalLayout)
55 self.webView = QtWebKit.QWebView(HttpWidget)
56 self.webView.setUrl(QtCore.QUrl(_fromUtf8("about:blank")))
57 self.webView.setObjectName(_fromUtf8("webView"))
58 self.verticalLayout.addWidget(self.webView)
59
60 self.retranslateUi(HttpWidget)
61 QtCore.QMetaObject.connectSlotsByName(HttpWidget)
62
63 def retranslateUi(self, HttpWidget):
64 HttpWidget.setWindowTitle(QtGui.QApplication.translate("HttpWidget", "Form", None, QtGui.QApplication.UnicodeUTF8))
65 self.back.setToolTip(QtGui.QApplication.translate("HttpWidget", "Back", None, QtGui.QApplication.UnicodeUTF8))
66 self.back.setText(QtGui.QApplication.translate("HttpWidget", "Back", None, QtGui.QApplication.UnicodeUTF8))
67 self.next.setToolTip(QtGui.QApplication.translate("HttpWidget", "Next", None, QtGui.QApplication.UnicodeUTF8))
68 self.next.setText(QtGui.QApplication.translate("HttpWidget", " Next", None, QtGui.QApplication.UnicodeUTF8))
69 self.stop.setToolTip(QtGui.QApplication.translate("HttpWidget", "Stop", None, QtGui.QApplication.UnicodeUTF8))
70 self.stop.setText(QtGui.QApplication.translate("HttpWidget", "Stop", None, QtGui.QApplication.UnicodeUTF8))
71 self.reload.setToolTip(QtGui.QApplication.translate("HttpWidget", "Reload", None, QtGui.QApplication.UnicodeUTF8))
72 self.reload.setText(QtGui.QApplication.translate("HttpWidget", "Reload", None, QtGui.QApplication.UnicodeUTF8))
73
74 from PyQt4 import QtWebKit
[图片] TM截图.jpg
为QT的Webkit 编写插件 - Braincol - 博客园
为QT的Webkit 编写插件
为了允许的QWebView加载插件,必须使能QWebView的Javascript和Plugins属性,使能方法为:
QWebSettings::globalSettings()->setAttribute(QWebSettings::JavascriptEnabled,true);
QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled,true);
或者
//这里假设webView是QWebView的对象:QWebView *webView;
webView->settings()->setAttribute(QWebSettings::JavascriptEnabled,true);
webView->settings()->setAttribute(QWebSettings::PluginsEnabled,true);
然后为QWebView添加插件工厂,这个插件工厂中包含了QWebView中所有可用的插件库,当然这个插件工厂中包含哪些插件得由我们程序员来定。添加插件工厂的方法为:
//为QWebView添加插件工厂,即告诉QWebView有哪些插件可用。
//这里的 WebkitPluginFactory 是Qt的虚类 QWebPluginFactory 的实现类,后面会讲到这个类。
webView->page()->setPluginFactory(new WebkitPluginFactory(this));
下面我们就来实现这个插件工厂类WebkitPluginFactory, 主要需要实现的就是 QWebPluginFactory 中的两个虚函数:
virtual QObject *create(const QString &mimeType, const QUrl &url,
const QStringList &argumentNames,const QStringList & argumentValues )const = 0;
virtual QList<Plugin> plugins () const = 0;
plugins() 方法为获取所有可用的插件列表, create() 方法则根据mimeType等参数来决定创建相应的插件。下面给出这个类的实现代码:
webkitpluginfactory.h :
#ifndef WEBKITPLUGINFACTORY_H
#define WEBKITPLUGINFACTORY_H
#include <QWebPluginFactory>
#include <QUrl>
#include "webkitplugininterface.h"
class WebkitPluginFactory : public QWebPluginFactory
{
Q_OBJECT
public:
WebkitPluginFactory(QObject *parent = 0);
QObject *create ( const QString & mimeType, const QUrl & url, const QStringList & argumentNames, const QStringList & argumentValues ) const;
QList<QWebPluginFactory::Plugin> plugins () const;
private:
// 插件列表
mutable QList<QList<QWebPluginFactory::Plugin> > pluginslist;
//插件接口,这个接口是我们自定义的插件的同意接口。
//这个接口在后面会讲到。
mutable QList<WebKitPluginInterface *> interfaces;
};
#endif // WEBKITPLUGINFACTORY_H
webkitpluginfactory.cpp :
#include "webkitpluginfactory.h"
#include <QPluginLoader>
#include <QDebug>
#include <QDir>
WebkitPluginFactory::WebkitPluginFactory(QObject *parent) :
QWebPluginFactory()
{
qDebug()<<"debug : WebkitPluginFactory";
}
QList<QWebPluginFactory::Plugin> WebkitPluginFactory::plugins () const
{
//const char * s=getenv("BROWSER_PLUGIN_DIR");
const char *s = "/home/nxx/FlashPlugin-build-desktop";
static bool isFirst=true;
static QList<QWebPluginFactory::Plugin> plugins;
if(!isFirst)
{
return plugins;
}
isFirst=false;
plugins.clear();
QString spath;
if(s)
spath=s;
else
spath=".";
QDir dir(spath);
QStringList filters;
QString abspath=dir.absolutePath();
qDebug()<<abspath;
//获取指定目录下的所有插件,linux下是插件库的后缀为so,windows下则是dll,
filters<<"lib*.so";
QStringList files=dir.entryList(filters);
qDebug()<<"files: "<<files;
foreach(QString file,files)
{
qDebug()<<QLibrary::isLibrary(file);
file=dir.filePath(file);
qDebug()<<"path: "<<file;
QPluginLoader loader(file);
QObject * obj= loader.instance();
if(obj==0)
qDebug()<<"error: "<<loader.errorString();
//下面是载入自定义的接口,只有这样才能支持动态插件创建,如果固定死了,将不利于扩展
WebKitPluginInterface * interface= qobject_cast<WebKitPluginInterface*> (obj);
if(interface==0)
{
qDebug()<<"ignore error when loading so" ;
continue;
}
qDebug()<<"load plugins: "<<interface->plugins().at(0).name;
plugins.append(interface->plugins());
pluginslist.append(interface->plugins());
interfaces.append(interface);
}
if(plugins.isEmpty()){
qDebug()<<"no plugins is loaded!";
}
return plugins;
}
QObject * WebkitPluginFactory::create ( const QString & mimeType, const QUrl & url, const QStringList & argumentNames, const QStringList & argumentValues ) const
{
for(int i=0;i<pluginslist.size();i++)
{
for( int j=0;j< pluginslist[i].size();j++)
{
foreach(QWebPluginFactory::MimeType mt, pluginslist[i][j].mimeTypes)
{
if(mt.name == mimeType) //更具MIME类型,创建相应的插件实例
return interfaces[i]->
create( mimeType, url, argumentNames, argumentValues);
}
}
}
return NULL; //如果没有,直接返回NULL,webkit会进行处理的
}
下面就可以开始编写插件库。首先我们定义插件的统一接口,然后每个插件类只需实现该接口就行了,这样有利于扩展插件库。
自定义的插件接口:
webkitplugininterface.h :
#ifndef WEBKITPLUGININTERFACE_H
#define WEBKITPLUGININTERFACE_H
#include <QWebPluginFactory>
class WebKitPluginInterface
{
public:
virtual ~WebKitPluginInterface(){};
virtual QList<QWebPluginFactory::Plugin> plugins()const =0;
virtual QObject *create(const QString &mimeType,
const QUrl &url,
const QStringList &argumentNames,
const QStringList &argumentValues) const =0;
};
//声明WebKitPluginInterface为一个接口
Q_DECLARE_INTERFACE(WebKitPluginInterface, "com.plugin.uvchip.www/1.0")
#endif // WEBKITPLUGININTERFACE_H
上面的那段代码中的Q_DECLARE_INTERFACE() 是在定义接口是必须添加声明。下面是Qt对这个宏的说明:
Q_DECLARE_INTERFACE ( ClassName, Identifier )
This macro associates the given Identifier (a string literal) to the interface class called ClassName. The Identifier must be unique.
下面我们开始实现这个接口:
我们将flashplugin编译成库,这样就可以供插件工厂WebkitPluginFactory加载访问了。
flashplugin.h :
#ifndef FLASHPLUGIN_H
#define FLASHPLUGIN_H
#if defined(FLASHPLUGIN_LIBRARY)
# define FLASHPLUGINSHARED_EXPORT Q_DECL_EXPORT
#else
# define FLASHPLUGINSHARED_EXPORT Q_DECL_IMPORT
#endif
#include "webkitplugininterface.h"
#include <QtPlugin>
class FLASHPLUGINSHARED_EXPORT FlashPlugin : public QObject, public WebKitPluginInterface {
Q_OBJECT
Q_INTERFACES(WebKitPluginInterface) //声明WebKitPluginInterface是一个接口
public:
FlashPlugin(): WebKitPluginInterface(){};
~FlashPlugin(){};
QList<QWebPluginFactory::Plugin> plugins()const ;
QObject *create(const QString &mimeType,
const QUrl &url,
const QStringList &argumentNames,
const QStringList &argumentValues) const ;
};
#endif // FLASHPLUGIN_H
flashplugin.cpp :
#include "flashplugin.h"
#include <QTextEdit>
#include <QUrl>
#include <QDebug>
QList<QWebPluginFactory::Plugin> FlashPlugin::plugins()const
{
QWebPluginFactory::MimeType mimeType;
mimeType.name="application/x-shockwave-flash";
mimeType.description=QObject::tr("flash");
mimeType.fileExtensions.append(".flv");
mimeType.fileExtensions.append(".f4v");
mimeType.fileExtensions.append(".swf");
QList<QWebPluginFactory::MimeType> mimeTypes;
mimeTypes.append(mimeType);
QWebPluginFactory::Plugin plugin;
plugin.name=QObject::tr("External Video viewer plugin");
plugin.description=QObject::tr("Use vlc to open video files !!!");
plugin.mimeTypes=mimeTypes;
QList<QWebPluginFactory::Plugin> plugins ;
plugins.append(plugin);
return plugins;
}
QObject *FlashPlugin::create(const QString &mimeType,
const QUrl &url,
const QStringList &argumentNames,
const QStringList &argumentValues) const
{
QTextEdit * edit= new QTextEdit();
edit->setObjectName("我是插件");
edit->setPlainText(mimeType + " : " + url.toString() +"\n\n"
+QString::fromUtf8("这里本来是需要adobeFlash插件的,")+"\n"
+QString::fromUtf8("但现在替换成了我们自定义的插件(QTextEdit插件了)。") );
Q_UNUSED(argumentNames);
Q_UNUSED(argumentValues);
qDebug()<<"create flash plugin";
return edit;
}
//Q_EXPORT_PLUGIN2()必不可少,
//只有这样FlashPlugin插件类才为外部可见,插件名为WebkitPluginFlash
Q_EXPORT_PLUGIN2(WebkitPluginFlash, FlashPlugin)
Q_EXPORT_PLUGIN2 在Qt帮助文档中的说明如下:
Q_EXPORT_PLUGIN2 ( PluginName, ClassName )
This macro exports the plugin class ClassName for the plugin specified by PluginName. The value of PluginName should correspond to the TARGET specified in the plugin's project file.
There should be exactly one occurrence of this macro in the source code for a Qt plugin, and it should be used where the implementation is written rather than in a header file.
Q_EXPORT_PLUGIN2(WebkitPluginFlash, FlashPlugin) 中的WebkitPluginFlash为编译之后生成的库的名字,这里的生成的库的完整名字为:libWebkitFlashPlugin.so, FlashPlugin 是插件类名。
现在只要把生成的libWebkitFlashPlugin.so插件库拷贝到webkitpluginfactory插件工厂能搜到的目录下就行了(本例中我在webkitpluginfactory.cpp中指定的位置为 const char *s = "/home/nxx/FlashPlugin-build-desktop";)。
上面的插件库和前面的工厂类,QWebView对象组合在一起就可以实现:
当用QWebView打开包含了需要 mimeType.name="application/x-shockwave-flash" 类型的插件的网页的时候,就会调用到我们自定义的flashplugin插件了。
效果如下:
pluginView