0

私はBlackberry 10 Cascades、QML、およびC++ QTで作業しており、私が書いた小さなphp WebサービスからXMLデータを取得して、使用しているBlackberry 10 Dev Alpha Simulatorのリストにロードしようとしています-しかし、それは動作していません。

つまり、xml データは QML ドキュメントの ListView に読み込まれず、Blackberry シミュレータの画面に表示されません。その仕事を得るには助けが必要です。

通常の http リクエストを含む例から始めて、目的に合わせてカスタマイズするように変更しました (これは http ポスト リクエストです)。(このコードは、テキスト フィールドに世代番号 (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

また、プロジェクト ディレクトリの assets/model.xml の下に、次の内容の xml フォルダーが保存されています。

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

また、ここに私が書いた App.cpp コードがあります:

#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() ストリームは、生成パラメーターが 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>"

世代パラメータが 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>"

Generation パラメータが 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>"

Generation パラメータが 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>"

パラメータ生成が foo であるその他の場合 (foo はプレースホルダーです):

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

なぜこれが機能しないのか、よくわかりません。他の例を探して、それを使用してコードを適切に機能させる方法を見つけようとしましたが、うまくいきませんでした。

この質問が長いことは承知していますが、最良の回答を得るために、私が行っていたことについてできるだけ詳しく説明したいと思いました. そうは言っても、私の main.cpp ファイルは関連性があるとは思えないので、誰かがそれを見るように頼まない限り、ここには入れません。

(xml コードのゲーム タグに title 属性を追加し、これらのタグの主なデータ値と同じ値を入れました。

<game>yellow</game>

の中へ

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

title 属性を使用せずに機能させようとした後、前者だけで問題が解決するかもしれないと思ったので、少しハックでしたが、解決しませんでした。理想的には、ゲーム タグに title 属性がある場合とない場合の両方で、これを機能させる方法を見つけたいと考えています。

4

1 に答える 1

0

問題が見つかりました。PHP Web サービスから xml ヘッダー コードを削除する必要がありました。

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

そして、これを data/model.xml ファイルから削除する必要がありました:

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

そして、ファイルには次のコードだけがあります。

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

QML ドキュメントのタグ間のデータを取得する方法がまだわかりません。現在、タグに「title」属性を指定して ListItemData.title を使用していますが、ゲームの開始タグと終了タグの間にコンテンツが必要です。

于 2012-08-24T20:52:08.820 に答える