PyQt写的浏览单web页面的browser

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

原文地址:https://www.cnblogs.com/lexus/p/2828666.html