2012-08-24 44 views
0

我正在Blackberry 10級聯,QML和C++ QT中工作,我試圖從我寫的一個小型php webservice中獲取一些XML數據,以加載到在我使用的Blackberry 10 Dev Alpha模擬器上的列表 - 但它不起作用。使Blackberry中的listItemComponents中顯示XML數據10 C++中的級聯QML

這就是xml數據不會加載到QML文檔的ListView中,以顯示在Blackberry Simulator的屏幕上。我需要幫助才能完成這項工作。

我已經開始了一個涉及常規http請求的示例,並對其進行了修改以使其根據我的目的(這是http post請求)進行定製。 (此代碼需要在文本字段中生成一代(1-5)),並打印出該代的小精靈遊戲的顏色列表)。

這是QML文件我開始:

import bb.cascades 1.0 

TabbedPane { 
    activePane: Page { 
     actions: [ 
      // An action item that calls the C++ function that retrieves 
      // the contact list 
      ActionItem { 
       title: "Refresh" 
       onTriggered: app.initiateRequest() 
      } 
     ]  
     content: Container { 
      layout: DockLayout {} 

      // A list that has two list item components, one for a header 
      // and one for contact names. The list has an object name so 
      // that we can set the data model from C++. 
      ListView { 
       objectName: "list" 
       layout: FlowListLayout { 
        topPadding: 6 
        rightPadding: 6 
        bottomPadding: 6 
        leftPadding: 6 
       } 
       // A simple data model is loaded with just a header. 
       // This will be replaced when we load the real one 
       // from C++. 
       dataModel: XmlDataModel { 
        source: "model.xml" 
       } 

       listItemComponents: [ 
        // The header list item displays a title along with a counter 
        // that displays the number of children 
        ListItemComponent { 
         type: "header" 
         HeaderListItem { 
          topMargin: 8 
          title: ListItemData.title 
          subtitle: (ListItem.initialized ? 
           ListItem.view.dataModel 
            .childCount(ListItem.indexPath) : 0); 
         } 
        }, 
        // The contact list item displays the name of the contact 
        ListItemComponent { 
         type: "contacts" 
         StandardListItem { 
          title: ListItemData.title 
         } 
        } 
       ] 
      } 
      // The activity indicator has an object name set so that 
      // we can start and stop it from C++ 
      ActivityIndicator { 
       objectName: "indicator" 
       layoutProperties: DockLayoutProperties { 
        verticalAlignment: VerticalAlignment.Fill 
        horizontalAlignment: HorizontalAlignment.Fill 
       } 
      } 
     } // Ends the root Container 
    } // Ends the Page 
} // Ends the TabbedPane 

這是我的QML文件:

import bb.cascades 1.0 

TabbedPane { 
    activePane: Page { 
     actions: [ 
      // An action item that calls the C++ function that retrieves 
      // the contact list 
      ActionItem { 
       title: "Refresh" 
       onTriggered: app.initiateRequest(txtGen.text) 
      } 
     ]  
     content: Container { 
      layout: StackLayout {} 

      Button { 
       text: "Get Games" 
       onClicked: app.initiateRequest(txtGen.text) 
      } 

      Label { 
       text: "Enter Generation (1-5)" 
      } 

      TextField { 
       id: txtGen 
      } 

      // A list that has two list item components, one for a header 
      // and one for contact names. The list has an object name so 
      // that we can set the data model from C++. 
      ListView { 
       objectName: "list" 
       layout: FlowListLayout { 
        topPadding: 6 
        rightPadding: 6 
        bottomPadding: 6 
        leftPadding: 6 
       } 
       // A simple data model is loaded with just a header. 
       // This will be replaced when we load the real one 
       // from C++. 
       dataModel: XmlDataModel { 
        source: "model.xml" 
       } 

       listItemComponents: [ 
        // The header list item displays a title along with a counter 
        // that displays the number of children 
        ListItemComponent { 
         type: "games" 
         HeaderListItem { 
          topMargin: 8 
          title: ListItemData.generation 
          subtitle: (ListItem.initialized ? 
           ListItem.view.dataModel 
            .childCount(ListItem.indexPath) : 0); 
         } 
        }, 
        // The contact list item displays the name of the contact 
        ListItemComponent { 
         type: "game" 
         StandardListItem { 
          title: ListItemData.title 
         } 
        } 
       ] 
      } 
      // The activity indicator has an object name set so that 
      // we can start and stop it from C++ 
      ActivityIndicator { 
       objectName: "indicator" 
       layoutProperties: DockLayoutProperties { 
        verticalAlignment: VerticalAlignment.Fill 
        horizontalAlignment: HorizontalAlignment.Fill 
       } 
      } 
     } // Ends the root Container 
    } // Ends the Page 
} // Ends the TabbedPane 

我也有我的下項目的資產/ model.xml存儲在XML文件夾目錄, 與以下內容:

<?xml version="1.0" encoding="utf-8"?> 
<xml> 
    <games> 
    </games> 
</xml> 

此外,這裏是App.cpp代碼I寫道:

#include "app.hpp" 

#include <bb/cascades/Application> 
#include <bb/cascades/QmlDocument> 
#include <bb/cascades/AbstractPane> 
#include <bb/cascades/Button> 
#include <bb/cascades/TextField> 
#include <QDir> 

using namespace bb::cascades; 

App::App() 
{ 
    // Load the QML document and retrieve the root node 
    QmlDocument *qml = QmlDocument::create("main.qml"); 
    mRoot = qml->createRootNode<AbstractPane>(); 

    // Retrieve the activity indicator from QML so that we can start 
    // and stop it from C++ 
    mActivityIndicator = mRoot->findChild<ActivityIndicator*>("indicator"); 

    // Retrieve the list so we can set the data model on it once 
    // we retrieve it 
    mListView = mRoot->findChild<ListView*>("list"); 

    //mTextField = mRoot->findChild<TextField*>("textField"); 

    //qDebug() << "Generation: " << mTextField->text(); 

    // Expose this class to QML so that we can call its functions from there 
    qml->setContextProperty("app", this); 

    // Create a network access manager and connect a custom slot to its 
    // finished signal 
    mNetworkAccessManager = new QNetworkAccessManager(this); 

    Q_ASSERT(connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)))); 

    // Displays a warning message if there's an issue connecting the signal 
    // and slot. This is a good practice with signals and slots as it can 
    // be easier to mistype a slot or signal definition 
    //Q_ASSERT(result); 
    //Q_UNUSED(result); 

    // Create a file in the application's data directory 
    mFile = new QFile("data/model.xml"); 

    // Set the scene using the root node 
    Application::setScene(mRoot); 
} 

void App::initiateRequest(QString text) 
{ 
     // Start the activity indicator 
    mActivityIndicator->start(); 

    // Create and send the network request 
    QNetworkRequest request = QNetworkRequest(); 
    request.setUrl(QUrl("http://192.168.1.109/TESTWEBSERVICE/MAKEXML.php")); //https://developer.blackberry.com/cascades/files/documentation/device_platform/networking/model.xml")); 
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); 

    QByteArray bytes; 
    QUrl params; 

    params.addQueryItem(QString::fromStdString("generation"), text); 

    bytes = params.encodedQuery(); 
    mNetworkAccessManager->post(request, bytes); 
} 

void App::requestFinished(QNetworkReply* reply) 
{ 
    // Check the network reply for errors 
    if (reply->error() == QNetworkReply::NoError) { 

     // Open the file and print an error if the file cannot be opened 

     if (!mFile->open(QIODevice::ReadWrite)) 
     { 
      qDebug() << "\n Failed to open file"; 
      return; 
     } 

     mFile->resize(0); 

     // Write to the file using the reply data and close the file 
     QByteArray xml = reply->readAll(); 
     mFile->write(xml); 
     qDebug() << xml; 

     mFile->flush(); 
     mFile->close(); 

     // Create the data model using the contents of the file. The 
     // location of the file is relative to the assets directory. 
     XmlDataModel *dataModel = new XmlDataModel(); 

     dataModel->setSource(QUrl("../../../data/model.xml")); 

     // Set the new data model on the list and stop the activity indicator 
     mListView->setDataModel(dataModel); 
     mActivityIndicator->stop(); 
    } 
    else 
    { 
     qDebug() << "\n Problem with the network"; 
     qDebug() << "\n" << reply->errorString(); 
    } 
} 

這裏是我的App.h文件:

#ifndef APP_H 
#define APP_H 

#include <QObject> 
#include <QFile> 
#include <bb/cascades/ActivityIndicator> 
#include <bb/cascades/ListView> 
#include <bb/cascades/XMLDataModel> 
#include <bb/cascades/AbstractPane> 
#include <bb/cascades/TextField> 

using namespace bb::cascades; 

/*! 
* @brief Application GUI object 
*/ 
class App : public QObject 
{ 
    Q_OBJECT 

public: 
    /*! 
    * Constructor. 
    */ 
    App(); 
    /*! 
    * Initiates the network request. 
    */ 
    Q_INVOKABLE void initiateRequest(QString text); 

private slots: 
    /*! 
    * Handles the network reply. 
    */ 
    void requestFinished(QNetworkReply* reply); 

private: 
    AbstractPane *mRoot; 
    ActivityIndicator *mActivityIndicator; 
    ListView *mListView; 
    TextField *mTextField; 
    QNetworkAccessManager *mNetworkAccessManager; 
    QFile *mFile; 
    QString apiKey; 
    QString apiString; 
}; 

#endif // ifndef APP_H 

而且QDebug()流打印出的一代paramater以下爲1:

"<?xml version="1.0" encoding="utf-8"?> 
<xml> 
    <games generation="1"> 
    <game title="green">green</game> 
    <game title="red">red</game> 
    <game title="blue">blue</game> 
    <game title="yellow">yellow</game> 
    </games> 
</xml>" 

對於一代參數爲2:

"<?xml version="1.0" encoding="utf-8"?> 
<xml> 
    <games generation="2"> 
    <game title="gold">gold</game> 
    <game title="silver">silver</game> 
    <game title="crystal">crystal</game>  
    </games> 
</xml>" 

爲了產生paramater爲3:

"<?xml version="1.0" encoding="utf-8"?> 
<xml> 
    <games generation="3"> 
    <game title="ruby">ruby</game> 
    <game title="sapphire">sapphire</game> 
    <game title="emerald">emerald</game>  
    </games> 
</xml>" 

用於產生paramater爲4:

"<?xml version="1.0" encoding="utf-8"?> 
<xml> 
    <games generation="4"> 
    <game title="perl">perl</game> 
    <game title="diamond">diamond</game> 
    <game title="platinum">platinum</game> 
    </games> 
</xml>" 

用於產生paramater爲5:

"<?xml version="1.0" encoding="utf-8"?> 
<xml> 
    <games generation="5"> 
    <game title="black">black</game> 
    <game title="white">white</game> 
    <game title="black 2">black 2</game> 
    <game title="white 2">white 2</game>  
    </games> 
</xml>" 

爲別的,其中paramater生成是FOO( foo是一個佔位符):

"<?xml version="1.0" encoding="utf-8"?> 
<xml> 
    <games generation="foo"> 
    </games> 
</xml>" 

我不太確定,爲什麼這不起作用。我試着尋找其他的例子,看看我能否用它來弄清楚如何讓我的代碼正常工作,但這並沒有奏效。

我知道這個問題很長,但我想提供更多關於我在做什麼的細節,以獲得最佳答案。話雖如此,我並不認爲我的main.cpp文件是相關的,所以我不會把它放在這裏,除非有人要求看到它。

(我添加了title屬性我的遊戲標籤我的XML代碼,並把相同的值作爲主數據值的標籤,如車刀

<game>yellow</game> 

<game title="yellow">yellow</game> 

在試圖讓它與標題屬性一起工作之前,因爲我認爲這可能會解決我的問題,即使它有點駭人,但它沒有。理想情況下,我想弄清楚如何得到這個在遊戲標籤中有和沒有標題屬性的兩種工作方式,

回答

0

我發現了這個問題。我不得不從我的PHP Web服務中刪除XML頭碼,

header('Content-type: text/xml'); 
"<?xml version="1.0" encoding="utf-8"?> 

,我不得不從我的數據/ model.xml文件中刪除此:

<?xml version="1.0" encoding="utf-8"?> 

和文件中都只是這個代碼:

<xml> 
    <games> 
    </games> 
</xml> 

我還不確定如何獲取QML文檔中標籤之間的數據。現在我在標籤中使用帶有「title」屬性的ListItemData.title,但我希望在開始和結束遊戲標籤之間有內容。

+0

標記遊戲中的屬性'title'就像一個名爲的內部標記。所以,<遊戲標題=「my_title」>是一樣的 my_title,明白了嗎? –