在Ubuntu Scope中如何截获按钮事件并做我们想做的事情

来源:互联网 发布:淘宝网买东西注意什么 编辑:程序博客网 时间:2024/05/17 07:34

我们可以在Ubuntu的官方网站中得到关于Scope的更多的开发信息。在今天的这篇文章中,我们来主要介绍如何在Scope中截获在Preview中的按钮事件。在事件处理中,我们来做我们所需要的事情。在这篇文章中,我们将使用我们以前开发的weibo例子为例。在微博中,我们来发送一个我们需要的信息到微博中。最后我们的画面如下:


  




为了能够完成我们所需要的功能,我们首先下载我先前的代码: https://github.com/liu-xiao-guo/weibo。


我们首先在query.cpp中的run方法中加入如下的代码:


query.cpp


void Query::run(sc::SearchReplyProxy const& reply) {    // We will not show anything if the user does not login    if( !login(reply) )        return;    sc::CategoryRenderer rdr_new_blog(NEW_BLOG);    sc::Category::SCPtr cat_new_blog;    cat_new_blog = reply->lookup_category("new_blog");    if (!cat_new_blog)        cat_new_blog = reply->register_category("new_blog", "", "", rdr_new_blog);    sc::CategorisedResult res_new_blog(cat_new_blog);    res_new_blog.set_title(_("Create new blog post"));    res_new_blog.set_uri("http://weibo.com");    res_new_blog["getusertext"] = "key_existence_only_has_meaning_not_this_value";//whether to get text from user in preview    res_new_blog["newblog"] = "key_existence_only_has_meaning_not_this_value";//new blog, not reply    res_new_blog["noart"] = "key_existence_only_has_meaning_not_this_value";//whether preview has art    reply->push(res_new_blog);....}

这里,我们创建了一个类似按钮的叫做“Create new blog post”的显示:



同时,我们在“CategorisedResult”加入了一些我们可以区别其它的显示的项比如:

    res_new_blog["getusertext"] = "key_existence_only_has_meaning_not_this_value";//whether to get text from user in preview    res_new_blog["newblog"] = "key_existence_only_has_meaning_not_this_value";//new blog, not reply    res_new_blog["noart"] = "key_existence_only_has_meaning_not_this_value";//whether preview has art    reply->push(res_new_blog);

这些项没有任何的实际的意义,只是在Preview中用来区分和其它的项有所不同。这样我们可以动态创建一些像,以使得对该项的处理和别的项不同。

preview.cpp


void Preview::run(sc::PreviewReplyProxy const& reply) {    // Support three different column layouts    sc::ColumnLayout layout1col(1), layout2col(2), layout3col(3);    // We define 3 different layouts, that will be used depending on the    // device. The shell (view) will decide which layout fits best.    // If, for instance, we are executing in a tablet probably the view will use    // 2 or more columns.    // Column layout definitions are optional.    // However, we recommend that scopes define layouts for the best visual appearance.    // Single column layout    layout1col.add_column( { "image", "header", "reviewId", "actions" });    // Two column layout    layout2col.add_column( { "image" });    layout2col.add_column( { "header", "reviewId", "actions" });    // Three cokumn layout    layout3col.add_column( { "image" });    layout3col.add_column( { "header", "reviewId", "actions" });    layout3col.add_column( { });    // Register the layouts we just created    reply->register_layout( { layout1col, layout2col, layout3col });    // Define the header section    sc::PreviewWidget w_header("header", "header");    // It has title and a subtitle properties    w_header.add_attribute_mapping("title", "title");    w_header.add_attribute_mapping("subtitle", "subtitle");    // Define the image section    sc::PreviewWidget w_image("image", "image");    // It has a single source property, mapped to the result's art property    w_image.add_attribute_mapping("source", "art");    Result result = PreviewQueryBase::result();    QString urlString(result["uri"].get_string().c_str());    // Create an Open button and provide the URI to open for this preview result    sc::PreviewWidget w_actions("actions", "actions");    sc::VariantBuilder builder;    builder.add_tuple({            {"id", Variant("open")},            {"label", Variant("Open")},            {"uri", sc::Variant(urlString.toStdString())} // uri set, this action will be handled by the Dash        });    w_actions.add_attribute_value("actions", builder.end());     PreviewWidgetList widgets({ w_header });    //used for blogging    PreviewWidget w_review("reviewId", "rating-input");    w_review.add_attribute_value("submit-label", Variant("Publish"));    w_review.add_attribute_value("visible", Variant("review"));    w_review.add_attribute_value("required", Variant("review"));    std::string reply_label = "Reply";    std::string max_chars_label = "140 characters max";    if (result.contains("newblog"))        w_review.add_attribute_value("review-label", Variant(max_chars_label));    if (result.contains("replyblog"))        w_review.add_attribute_value("review-label", Variant(reply_label + ": " + max_chars_label));    if (result.contains("getusertext"))        widgets.emplace_back(w_review);    if (!result.contains("noart"))    {        widgets.emplace_back(w_image);        widgets.emplace_back(w_actions);    }    // Push each of the sections    reply->push( widgets );}

在Preview的run中,我们加入了reviewId,它在result中包含有“getusertext”才显示。当其它项不包含“noart”时,才显示image及action。

  


添加对action的支持

scope.cpp


sc::ActivationQueryBase::UPtr Scope::perform_action(us::Result const& result,                                                     us::ActionMetadata const& metadata,                                                     std::string const& widget_id,                                                     std::string const& action_id){    return sc::ActivationQueryBase::UPtr(new Activation(result, metadata, widget_id, action_id, accessToken_));}

为例对任何一个action (比如上面图中的publish及open)在按钮被按下时,我们可以截获这个时间,我们需要创建一个独立的类:

activation.cpp


/* * Copyright (C) 2015 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program.  If not, see <http://www.gnu.org/licenses/>. * * Authored by: Kyle Nitzsche <kyle.nitzsche@canonical.com> * */#include <scope/activation.h>#include <unity/UnityExceptions.h>#include <QDebug>#include <QCoreApplication>#include <QNetworkAccessManager>#include <QNetworkReply>#include <QNetworkRequest>#include <QJsonArray>#include <QJsonDocument>#include <QJsonObject>namespace us = unity::scopes;Activation::Activation(us::Result const& result, us::ActionMetadata const& metadata, std::string const& widget_id, std::string const& action_id, std::string accessToken):        ActivationQueryBase(result, metadata),        action_id_(action_id),        accessToken_(accessToken){}Activation::~Activation(){}void Activation::cancelled(){}QString qstr_(std::string str){    return QString::fromStdString(str);}us::ActivationResponse Activation::activate(){    qDebug() << "==== in activate(). action_id: "<< QString::fromStdString(action_id_);    bool dash_handles = false;    if (result().contains("dash_activation"))        dash_handles = true;    else if (action_id_ == "profile_url")        dash_handles = true;    if (dash_handles)    {        qDebug() << "==== dash_activation";        return us::ActivationResponse(us::ActivationResponse::Status::NotHandled);    }    QString uri;    QString accessToken = QString::fromStdString(accessToken_);    QString params_qs;    QString message = QString("%1").arg(qstr_(action_metadata().scope_data().get_dict()["review"].get_string()));    if (result().contains("newblog"))    {        qDebug() << "==== NEW BLOG";        uri = QString("https://api.weibo.com/2/statuses/update.json?access_token=%1").arg(accessToken);        params_qs = QString("status=%1").arg(message);    }    else if (result().contains("replyblog"))    {        qDebug() << "==== REPLY BLOG";        //qDebug() << "==== token: " << accessToken;        uri = QString("https://api.weibo.com/2/statuses/repost.json?access_token=%1").arg(accessToken);        QString id_ = QString("id=%1").arg(qstr_(result()["idstring"].get_string()));        QString msg_ = QString("status=%1").arg(message);        params_qs = QString("%1&%2").arg(msg_,id_);        //qDebug() << "==== params_qs: " << params_qs;    }    us::ActionMetadata am = action_metadata();    //TODO: ensure text is 140 chars or less or warn user somehow    qDebug() << "====  microblog url:\n" << uri;    QByteArray params;    params.append(params_qs);    QEventLoop loop;    QNetworkAccessManager manager;    QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit()));    QObject::connect(&manager, &QNetworkAccessManager::finished, [](QNetworkReply *netReply) {        netReply->deleteLater();        QByteArray data_ba = netReply->readAll();        QJsonParseError err;        QJsonDocument doc = QJsonDocument::fromJson(data_ba, &err);        if (err.error != QJsonParseError::NoError) {            qCritical() << "Failed to parse server data: " << err.errorString();        }    });    QUrl url = QUrl(uri);    QNetworkRequest request(url);    QString mUserAgent = QString("%1 (Ubuntu)").arg("weibo-scope");    request.setRawHeader("User-Agent", mUserAgent.toStdString().c_str());    request.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");    manager.post(request, params);    loop.exec();    return us::ActivationResponse(us::ActivationResponse::Status::ShowDash);}

当任何一个按钮被按下后,“activate()”方法将被调用。我们可以通过截获这个事件来做任何我们想要做的事情。

整个项目的源码在: https://github.com/liu-xiao-guo/weibo_action


0 0
原创粉丝点击