2013-07-18 41 views
2

請幫助我,我堅持了這一個多星期。我發出了一個信號與我的cpp文件中的圖像。我需要替換我放置在imageView中的默認圖像在QMl使用這個發射的圖像。 這是我的完整代碼。在ImageView中動態設置imageSource黑莓10

PostHttp.hpp

/* Copyright (c) 2012 Research In Motion Limited. 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

#ifndef POSTHTTP_HPP 
#define POSTHTTP_HPP 
#include "qvariant.h" 
#include <bb/ImageData> 
#include <bb/cascades/GroupDataModel> 
#include <QtCore/QObject> 
#include <bb/data/JsonDataAccess> 
#include <bb/cascades/QListDataModel> 
#include <bb/cascades/Image> 
#include <bb/cascades/ImageView> 
#include <bb/cascades/CustomControl> 
namespace bb { 
namespace cascades { 
    class Container; 
} 
} 
    using namespace bb::cascades; 

class QNetworkAccessManager; 

class PostHttp: public QObject { 
Q_OBJECT 
public: 
PostHttp(QObject* parent = 0); 
bb::cascades::Image m_image; 
ImageView* imageView; 
Container* mRootContainer; 
bool createFolder(QString path); 
bool openAndSaveFile(QString filePathWithName, QNetworkReply* reply); 
public Q_SLOTS: 
void loginWebService(const QString &body, const QString &pass, 
     bool istoken); 
void newsFeedWebService(const qint16 num); 
void logoutWebService(); 
void imageFetcher(); 
void get(const QUrl &url); 
void post(const QVariantMap &body, const QUrl &url); 


Q_SIGNALS: 
void complete(const QVariantList &info); 
void newsfeedComplete(const QVariantList &info); 
void imageLoaded(const QVariant &image); 

private Q_SLOTS: 
void onGetReply(); 
void onNewsFeedReply(); 
void onImageReply(); 

Q_INVOKABLE void generatePage(); 
Q_INVOKABLE void loadImages(); 
private: 
bb::cascades::QListDataModel<QObject*>* m_model; 
QImage setImage(const QImage &image); 
bb::cascades::DataModel* model() const; 
QNetworkAccessManager* m_networkAccessManager; 
bb::data::JsonDataAccess* dataAccess; 

public: 
QString token; 

}; 

#endif 

PostHttp.cpp

#include "PostHttp.hpp" 
#include <QDebug> 
#include <QNetworkAccessManager> 
#include <QNetworkReply> 
#include <QNetworkRequest> 
#include <QSslConfiguration> 
#include <QUrl> 
#include <bb/data/JsonDataAccess> 
#include <QDateTime> 
#include <bb/cascades/AbstractPane> 
#include <bb/cascades/Application> 
#include <bb/cascades/QmlDocument> 
#include <bb/cascades/Page> 
#include <bb/cascades/StandardListItem> 
#include <QFile> 
#include <bb/ImageData> 
#include <QNetworkReply> 
#include <QNetworkDiskCache> 
#include <QDesktopServices> 
#include <bb/cascades/Image> 
#include <bb/cascades/Container> 
#include <bb/cascades/ImageView> 
#include <bb/cascades/ScalingMethod> 
#include <bb/cascades/DockLayout> 
#include <bb/cascades/controls/activityindicator.h> 
#include <bb/cascades/controls/scrollview.h> 
#include <bb/cascades/controls/page.h> 
#include <bb/cascades/NavigationPaneProperties> 
#include <bb/cascades/Color> 
using namespace bb::data; 
using namespace bb::cascades; 
using namespace bb::utility; 
QString globalTokenValue; 
int globalUserId; 
bool flag = true; 
bool flag1 = true; 
QVariantList data; 

PostHttp::PostHttp(QObject* parent) : 
    QObject(parent), m_networkAccessManager(
      new QNetworkAccessManager(this)), m_model(
      new QListDataModel<QObject*>()) { 

} 

//! [0] 

/** 
* PostHttp::post 
* 
* Make a network request to httpbin.org/post with POST data and get 
* the response 
*/ 
//! [1] 
void PostHttp::post(const QVariantMap &body, const QUrl &url) { 
JsonDataAccess jda; 
QByteArray jsonData; 
jda.saveToBuffer(*(&body), &jsonData); 

QByteArray postDataSize = QByteArray::number(jsonData.size()); 
QNetworkRequest request(*(&url)); 

request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); 
request.setHeader(QNetworkRequest::ContentLengthHeader, 
     QString(postDataSize).toUtf8()); 
//QNetworkReply* reply = m_networkAccessManager->post(request, body.toAscii()); 
qDebug() << "json" << jsonData; 
QNetworkReply* reply = m_networkAccessManager->post(request, jsonData); 
qDebug() << "strdgfyusujnm kjh " << (&url)->toString(); 
if ((&url)->toString() 
     == "http:///GetNewsFeed") { 
    connect(reply, SIGNAL(finished()), this, SLOT(onNewsFeedReply())); 
} else { 
    connect(reply, SIGNAL(finished()), this, SLOT(onGetReply())); 
} 
} 

void PostHttp::loginWebService(const QString &body, const QString &pass, 
    bool istoken) { 

qint64 date = QDateTime::currentMSecsSinceEpoch(); 
QString time = QString::number(date); 
QVariantMap data; 
QVariantMap loginData; 
QVariantMap devicedata; 
devicedata.insert("OS", "BlackBerry OS 6.0.0.706"); 
devicedata.insert("deviceId", "232BC441"); 
devicedata.insert("deviceModel", "9800"); 
devicedata.insert("screenSize", "480x360"); 
loginData.insert("device", devicedata); 
loginData.insert("email", *(&body)); 
loginData.insert("password", *(&pass)); 
loginData.insert("requestDate", "/Date(" + time + "+200)/"); 
data.insert("apiKey", "4f74721be9b51f24f065b044"); 
data.insert("data", loginData); 
data.insert("requestDate", "/Date(" + time + "+200)/"); 
if (istoken) { 

} else { 
    data.insert("token", ""); 
} 
const QUrl url(
     "http:///LoginRequest"); 
post(data, url); 
} 

void PostHttp::newsFeedWebService(const qint16 num) { 

qint64 date = QDateTime::currentMSecsSinceEpoch(); 
QString time = QString::number(date); 
QVariantMap data; 
QVariantMap newsfeedData; 
newsfeedData.insert("postId", 0); 
newsfeedData.insert("requestType", 2); 
newsfeedData.insert("requestedCount", num); 
newsfeedData.insert("userId", globalUserId); 
data.insert("apiKey", "4f74721be9b51f24f065b044"); 
data.insert("data", newsfeedData); 
data.insert("requestDate", "/Date(" + time + "+200)/"); 
data.insert("token", globalTokenValue); 
const QUrl url(
     "http:///GetNewsFeed"); 
if (flag == true) { 
    post(data, url); 
} 

} 

void PostHttp::logoutWebService() { 
qint64 date = QDateTime::currentMSecsSinceEpoch(); 
QString time = QString::number(date); 
QVariantMap data; 
QVariantMap logoutData; 
logoutData.insert("logoutRequestType", 1); 
logoutData.insert("userId", globalUserId); 
data.insert("apiKey", "4f74721be9b51f24f065b044"); 
data.insert("data", logoutData); 
data.insert("requestDate", "/Date(" + time + "+200)/"); 
data.insert("token", globalTokenValue); 
const QUrl url(
     "http:///LogoutUser"); 
post(data, url); 
} 

void PostHttp::imageFetcher() { 
const QUrl url(
     "http://upload.wikimedia.org/wikipedia/commons/e/e7/Nuvola_filesystems_services.png"); 
if (flag1 == true) { 
    get(url); 
} 
} 

void PostHttp::get(const QUrl &url) { 
QNetworkRequest request(*(&url)); 
QNetworkReply* reply = m_networkAccessManager->get(request); 
connect(reply, SIGNAL(finished()), this, SLOT(onImageReply())); 
} 
/** 
* PostHttp::onGetReply() 
* 
* SLOT 
* Read and return the http response from our http post request 
*/ 
void PostHttp::onGetReply() { 
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender()); 
QString response; 
if (reply) { 
    if (reply->error() == QNetworkReply::NoError) { 
     const int available = reply->bytesAvailable(); 
     if (available > 0) { 
      const QByteArray buffer(reply->readAll()); 
      response = QString::fromUtf8(buffer); 
      JsonDataAccess dataAccess; 
      QVariantMap results = 
         dataAccess.loadFromBuffer(response).toMap(); 
      QString token = (results["Token"]).value<QString>(); 
      int userId = (results["userId"]).value<int>(); 
      if (globalTokenValue == "") { 
       globalTokenValue = token; 
       globalUserId = userId; 
      } else 
       flag = false; 
      QString success = (results["Success"]).value<QString>(); 

     } 
    } else { 
     response = 
       tr("Error: %1 status: %2").arg(reply- >errorString(), 
         reply->attribute(
            QNetworkRequest::HttpStatusCodeAttribute).toString()); 
     qDebug() << response; 
    } 

    reply->deleteLater(); 
} 

if (response.trimmed().isEmpty()) { 
    response = tr("Unable to retrieve post response"); 
} 
qDebug() << "response" << response; 

} 

void PostHttp::onNewsFeedReply() { 

QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender()); 
QString response; 
if (reply) { 
    if (reply->error() == QNetworkReply::NoError) { 
     flag = false; 
     const int available = reply->bytesAvailable(); 
     if (available > 0) { 
      const QByteArray buffer(reply->readAll()); 
      response = QString::fromUtf8(buffer); 
      JsonDataAccess dataAccess; 
      QVariantMap results = 
         dataAccess.loadFromBuffer(response).toMap(); 
      data = results.value("Data").toList(); 
      qDebug() << "first element is" << data.first().toString(); 
      emit newsfeedComplete(data); 

     } 
    } 
} 

} 
void PostHttp::onImageReply() { 
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender()); 
QString response; 
QImage img; 
QString filePathWithName = "data/img/"; 
QString imageName; 

if (reply) { 
    if (reply->error() == QNetworkReply::NoError) { 
     flag1 = false; 
     const int available = reply->bytesAvailable(); 
     if (available > 0) { 
      const QByteArray buffer(reply->readAll()); 
      response = QString::fromUtf8(buffer); 
      img.loadFromData(buffer); 
      img = img.scaled(40, 40, Qt::KeepAspectRatioByExpanding); 
      const QImage swappedImage = img.rgbSwapped(); 
      const bb::ImageData imageData = bb::ImageData::fromPixels(
        swappedImage.bits(), bb::PixelFormat::RGBX, 
        swappedImage.width(), swappedImage.height(), 
        swappedImage.bytesPerLine()); 
      QByteArray byteArray = bb::utility::ImageConverter::encode(
        "image/png", imageData, 75); 
      qDebug() << "bytearray is" << byteArray; 
//    QVariant image(byteArray); 
      QVariant realImage(byteArray); 

      qDebug() << "imag of image is" << realImage; 
      emit imageLoaded(realImage); 
     } 
    } 
} 
} 
//! [1] 

最後我QML文件

NewsFeed.qml

import bb.cascades 1.0 
import Network.PostHttp 1.0 
import bb.cascades 1.0 
import "controls" 
import my.library 1.0 

Page { 
actions: [ 
    ActionItem { 
     title: "Logout" 
     onTriggered: { 
      netpost.logoutWebService(); 
      Application.quit(); 
     } 
     ActionBar.placement: ActionBarPlacement.OnBar 
    } 
] 
id:mainpage 
onCreationCompleted: { 
    Qt.mainImageview = imageviewid; 
} 
Container { 

    layout: DockLayout { 
    } 

    // The background image 
    ImageView { 
     horizontalAlignment: HorizontalAlignment.Fill 
     verticalAlignment: VerticalAlignment.Fill 
     imageSource: "asset:///images/background.png" 
    } 
    //! [0] 

    Container { 
     id : innercontainer 

     ActivityIndicator { 
      id: progressIndicator 

      horizontalAlignment: HorizontalAlignment.Fill 
      verticalAlignment: VerticalAlignment.Fill 
      onStarted: { 

      } 
      onCreationCompleted: { 
       progressIndicator.running = true; 

      } 

     } 

     ListView { 
      id: listView 
      objectName: "listView" 

      dataModel: ArrayDataModel { 
       id: myListModel 

      } 

      // Override default GroupDataModel::itemType() behaviour, which is to return item type "header" 
      listItemComponents: ListItemComponent { 
       id: listcomponent 
       // StandardListItem is a convivience component for lists with default cascades look and feel 
       StandardListItem { 
        title: ListItemData.postText 
        description: ListItemData.postDate 
        status: ListItemData.filePath 
        imageSource: "asset:///images/4.png" 
       } 

      } 
      layoutProperties: StackLayoutProperties { 
       spaceQuota: 1.0 
      } 
      horizontalAlignment: HorizontalAlignment.Fill 
      verticalAlignment: VerticalAlignment.Fill 

     } 


     Container { 
      id: root 
      layout: StackLayout { 
      } 
      Label { 
       text: ListItemData.postText 
       horizontalAlignment: HorizontalAlignment.Left 
       verticalAlignment: VerticalAlignment.Bottom 
      } 
      Label { 
       text: ListItemData.postDate 
       //     textStyle.fontSize: 5 
       horizontalAlignment: HorizontalAlignment.Right 
       verticalAlignment: VerticalAlignment.Bottom 
      } 

      attachedObjects: [ 
       QTimer { 
        id: timer 
        property int f: 0 
        interval: 5000 
        onTimeout: { 
         progressIndicator.running = false; 
         netpost.imageFetcher(); 
         netpost.newsFeedWebService("10"); 
        } 

       }, 
       PostHttp { 

        id: netpost 
        onComplete: { 
         progressIndicator.running = false; 
         progressIndicator.visible = false; 
         console.log("dsfdsafs"+netpost.model) 
         timer.stop(); 
        } 

        onImageLoaded:{ 
         console.log("value is image from cpp jhgsdh " + image) 
         imageviewid.setImageSource(image) 
        } 
        onNewsfeedComplete: { 
         console.log("response from newsfeed is "+info) 
         myListModel.append(info) 

        } 
       } 

      ] 
     } 

     onCreationCompleted: { 
      // this slot is called when declarative scene is created 
      // write post creation initialization here 
      console.log("Page - onCreationCompleted()") 

      // enable layout to adapt to the device rotation 
      // don't forget to enable screen rotation in bar-bescriptor.xml (Application->Orientation->Auto-orient) 
      OrientationSupport.supportedDisplayOrientation = SupportedDisplayOrientation.All; 

      // populate list view model with the sample data 
      timer.start(); 
      //    myListModel.load("app/native/assets/mydata.json") 

     } 
     ImageView { 
      id: imageviewid 
      imageSource: "asset:///images/4.png" 
      enabled: true 
      loadEffect: ImageViewLoadEffect.FadeZoom 

     } 
    } 
} 
} 

請幫助我。

+0

請顯示代碼,您在哪裏定義信號,插槽以及將它們綁定在一起的位置 – Sunseeker

+0

我已經編輯過,請檢查它。這裏PostHttp是定義信號的類。 在此先感謝。 –

+0

那麼你在哪裏連接你的'imageLoaded()'信號與某個插槽?我可以看到信號在PostHttp.cpp:251處發出,但是哪個函數處理這個信號? – Sunseeker

回答

1

因此,您已經使用QVariant參數定義了您的插槽,但嘗試使用ImageConverter::encode()調用返回的QByteArray類型發射它。

嘗試你的代碼的一部分改變這一點,並給它一個去:

QByteArray byteArray = bb::utility::ImageConverter::encode(QUrl(QDir::currentPath() + "/shared/camera/img.png"), imageData, 75); 
QVariant image(byteArray); 
emit imageLoaded(image); 

此外,仔細檢查無處不在,你聲明/定義這對信號/槽的你完全指定相同的參數符號

+0

感謝您的回覆。 執行上述解決方案後,出現如下錯誤'從'bool'轉換爲非標量類型'QByteArray'requested''。我認爲bb :: utility :: ImageConverter :: encode(QUrl(QDir :: currentPath()+「/shared/camera/img.png」),imageData,75);返回一個布爾值。所以在文檔中他們說編碼方法會返回一個編碼圖像。我的錯在哪裏? 我該如何糾正這個..? –

+0

這是一個重載函數,返回值取決於參數。以下是關於此的文檔 - https://developer.blackberry.com/cascades/reference/bb__utility__imageconverter.html基本上,您需要將信號參數的類型與插槽類型匹配。 – Sunseeker

+0

Thanks Agian。, 現在我得到了像這樣的圖像(來自終端) 圖像是QVariant(QByteArray,「PNG –

0

試試這個示例代碼和您的項目通過重新改變實現(即imageLoaded()信號等的情況下const QVariant&

1.QML FILE

import bb.cascades 1.0 

Page { 
    content: Container { 
     ListView { 
      dataModel: _app.model 

      function itemType (data, indexPath) { 
       return data["type"]; 
      } 
      listItemComponents: [ 

      ] 
     } 
    } 
} 

2.HPP FILE

#ifndef APP_HPP 
#define APP_HPP 

#include <QtCore/QObject> 
#include <QtNetwork/QNetworkAccessManager> 

#include <bb/cascades/QListDataModel> 

class App: public QObject 
{ 
    Q_OBJECT 

    Q_PROPERTY(bb::cascades::DataModel *model READ model NOTIFY modelChanged) 

public: 
    App(); 
    bb::cascades::DataModel * model() const; 

Q_SIGNALS: 

    void modelChanged(); 

private Q_SLOTS: 

    void handleNetworkData(QNetworkReply *reply); 

private: 

    mutable bb::cascades::QMapListDataModel *dataModel; 


    QNetworkAccessManager networkManager; 

}; 

#endif // APP_HPP 

3.CPP FILE

#include <bb/cascades/Page> 
#include <bb/cascades/QmlDocument> 
#include <bb/data/JsonDataAccess> 

#include "App.hpp" 

using namespace bb::cascades; 
using namespace bb::data; 

App::App() : 
{ 

    // Load up the QML for our view 
    QmlDocument *qml = QmlDocument::create("view.qml"); 

    // Provide a reference to this class 
    qml->setContextProperty("_app", this); 

    // Create the root node of this view 
    Page *view = qml->createRootNode<Page>(); 

    dataModel = new QMapListDataModel(); 

    // Hook this signal so we can respond to network replies 
    connect(&networkManager, SIGNAL(finished(QNetworkReply *)), this, 
      SLOT(handleNetworkData(QNetworkReply *))); 

    // Do the request 
    QUrl url = "http://jsonservice.com/news/headlines/"; 
    networkManager.get(QNetworkRequest(url)); 

} 

DataModel * App::model() const 
{ 
    return dataModel; 
} 

void App::handleNetworkData(QNetworkReply *reply) 
{ 

    if (!reply->error()) { 

     const QByteArray response(reply->readAll()); 

     JsonDataAccess jda; 
     QVariantMap results = jda.loadFromBuffer(response).toMap(); 

     // Get the relevant parts we want from the JSON 
     QVariantList posts = results["data"].toMap()["children"].toList(); 

     Q_FOREACH(QVariant post, posts) { 


      dataModel->append(post); 

     } 

    } 

    // Cleanup 
    reply->deleteLater(); 

}