QT中如何自定义"Notification Web API"

How to customize "Notification Web API" in the QT

我正在使用 QtWebkit, I managed to add support for Notification Web API 创建一个简单的浏览器,使用 QWebPage::setFeaturePermission

示例:

function notifyMe() {
    if (Notification.permission === "granted") {
        var notification = new Notification("Hi there!");
    } else if (Notification.permission !== "denied") {
        Notification.requestPermission(function(permission) {
            if (permission === "granted") {
                var notification = new Notification("Hi there!");
            }
        });
    }
}

<button onclick="notifyMe();">Notify me</button>

我的代码:

QObject::connect(page,
    SIGNAL(featurePermissionRequested(QWebFrame*, QWebPage::Feature)), this,
    SLOT(featurePermissionRequested(QWebFrame*,QWebPage::Feature))
);

...

void Form::featurePermissionRequested(QWebFrame* frame, QWebPage::Feature feature) {
    switch (feature) {
        case QWebPage::Notifications:
            qDebug() << "Notification";
            page->setFeaturePermission(frame, feature, QWebPage::PermissionGrantedByUser);
        break;
        case QWebPage::Geolocation:
            qDebug() << "GEO";
        break;
        default:
            qDebug() << "Unknown feature";
    }
}

每次单击 "Notify me" 按钮时,桌面上都会出现以下消息:

可以在QT中自定义通知吗?换句话说,离开类似于 GoogleChrome 或 Firefox,像这样:

新通知可以接受以下 2 个参数:

var notification = new Notification(title, options);

作为选项对象的一部分,您可以传递要在通知中显示的 'body' 和 'icon'。

要在 QtWebkit 中自定义 Notifications Web API,您必须使用 "Webkit plugins",换句话说,创建一个插件并放入 qtdir/plugins/webkit.

Note: For create plugin is needed <QtWebKit/QWebKitPlatformPlugin> class

创建插件:

  • 在 QtCreator 中创建项目
  • .pro文件中使用(例子src.pro):

    TARGET = $$qtLibraryTarget(mywebkitplugin)
    TEMPLATE = lib
    CONFIG += plugin
    
    HEADERS += $$[QT_INSTALL_HEADERS]/QtWebKit/qwebkitplatformplugin.h \
        mywebkitplugin.h
    
    SOURCES += \
        mywebkitplugin.cpp
    
    Release:DESTDIR     = $$PWD/bin/release
    Release:UI_DIR      = $${DESTDIR}/.ui
    Release:MOC_DIR     = $${DESTDIR}/.moc
    Release:RCC_DIR     = $${DESTDIR}/.rcc
    Release:OBJECTS_DIR = $${DESTDIR}/.obj
    
    Debug:DESTDIR       = $$PWD/bin/debug
    Debug:UI_DIR        = $${DESTDIR}/.ui
    Debug:MOC_DIR       = $${DESTDIR}/.moc
    Debug:RCC_DIR       = $${DESTDIR}/.rcc
    Debug:OBJECTS_DIR   = $${DESTDIR}/.obj
    
  • 创建mywebkitplugin.h

    #ifndef MYWEBKITPLUGIN_H
    #define MYWEBKITPLUGIN_H
    
    #include <QtWebKit/QWebKitPlatformPlugin>
    
    class MyWebKitPlugin : public QObject, public QWebKitPlatformPlugin
    {
        Q_OBJECT
        Q_INTERFACES(QWebKitPlatformPlugin)
    
    #if QT_VERSION >= 0x050000
        Q_PLUGIN_METADATA(IID "org.qtwebkit.QtWebKit.QtWebPlugin")
    #endif
    
    public:
        explicit MyWebKitPlugin();
        ~MyWebKitPlugin();
    
        bool supportsExtension(Extension ext) const;
        QObject* createExtension(Extension ext) const;
    };
    
    #endif // MYWEBKITPLUGIN_H
    
  • 创建mywebkitplugin.cpp

    #include "mywebkitplugin.h"
    #include "notification/notification.h"
    
    MyWebKitPlugin::MyWebKitPlugin()
    {
    }
    
    MyWebKitPlugin::~MyWebKitPlugin()
    {
    }
    
    bool MyWebKitPlugin::supportsExtension(Extension ext) const
    {
        return ext == Notifications;
    }
    
    QObject* MyWebKitPlugin::createExtension(Extension ext) const
    {
        switch (ext) {
            case Notifications:
                return new Notification();
    
            default:
                return 0;
        }
    }
    
    //for QT-4.8
    #if QT_VERSION < 0x050000
    Q_EXPORT_PLUGIN2(webkitplugin, MyWebKitPlugin);
    #endif
    
  • 创建 notification 文件夹

  • 通知文件夹中放入通知class:

    notification.h

    #ifndef NOTIFICATION_H
    #define NOTIFICATION_H
    
    #include <QtWebKit/QWebKitPlatformPlugin>
    
    class Notification : public QWebNotificationPresenter
    {
        Q_OBJECT
    
    public:
        explicit Notification();
        ~Notification();
    
        void showNotification(const QWebNotificationData* data);
    
    signals:
        void notificationClosed();
        void notificationClicked();
    };
    
    #endif // NOTIFICATION_H
    

    notification.cpp

    #include "notification.h"
    #include <QDebug>
    
    Notification::Notification() : QWebNotificationPresenter()
    {
        qDebug() << "Create: Notification";
    }
    
    Notification::~Notification()
    {
        qDebug() << "Delete: this (Notification)";
    }
    
    void Notification::showNotification(const QWebNotificationData* data)
    {
        qDebug() << "title:" << data->title();
        qDebug() << "icon:" << data->iconUrl();
        qDebug() << "message:" << data->message();
        qDebug() << "opener page:" << data->openerPageUrl();
    }
    

创建您的通知自定义更改 Notification::showNotification(const QWebNotificationData* data) 内容并使用 QWebNotificationData* dataJavaScript API.

获取数据
  • 创建notification.pri(包含在src.pro):

    QT += network
    
    HEADERS += \
        $$PWD/notification.h
    
    SOURCES += \
        $$PWD/notification.cpp
    
  • src.pro中添加notification.pri:

    include($$PWD/notification/notification.pri)
    

Compiling/build:

  • 在 QtCreator
  • 中打开 src.pro
  • 点击Build(释放模式)(或使用Ctrl+B)按钮(不要点击Run按钮中的不要使用 Ctrl+R )
  • 关闭src.pro
  • 转到 src.pro
  • 所在的文件夹
  • (如果是发布模式)打开bin/release文件夹
  • (如果是调试模式)打开 bin/debug 文件夹
  • (如果是release模式)复制mywebkitplugin.dllQtDir/plugins/webkit/mywebkitplugin.dll (eg with mingw: C:/qt/qt5.4/mingw/plugin/webkit/mywebkitplugin.dll)
  • (如果是调试模式)将mywebkitplugind.dll复制到QtDir/plugins/webkit/mywebkitplugind.dll(例如使用mingw:C:/qt/qt5.4/mingw/plugin/webkit/mywebkitplugind.dll
  • 如果 webkit 文件夹不存在,请创建它。
  • 使用 QWebView 打开您的项目并测试 Notification Web API

当运行一个项目使用QWebView时,它会自动加载dll(你的项目不需要额外配置)并且"replace"默认Notifications(Windows 中的 QtWebkit 使用 SystemTrayIcon 显示 Notification Web API)为您的 "custom widget"。

插件项目的文件夹结构:

mywebkitplugin
├── `src.pro`
├── mywebkitplugin.h
├── mywebkitplugin.cpp
└── notification
    ├── notification.h
    ├── notification.cpp
    └── `notification.pri`