Access C++ function from multiple QML files
Hello, hope someone can help me with a small problem, is there anything special that needs to be declared or registered for a C++ function to be available in different QML files. At the moment I can only access the functions from my mail.qml file.
I have a MyListView.qml file which customizes a listview for me, and I can't get the C++ functions to work in the QML.
Ohh, forgot to mention i'm a total noob when it comes to C++ and QML, but want to take stab at it.
CODE:
mail.cpp
Code:
// List with context menu project template
#include "tldrapp.h"
#include <bb/cascades/Application>
#include <QLocale>
#include <QTranslator>
// include JS Debugger / CS Profiler enabler
// this feature is enabled by default in the debug build only
#include <Qt/qdeclarativedebug.h>
#include <bb/data/DataSource>
#include <bb/data/DataSourceType>
#include <bb/data/DataSource>
using namespace bb::cascades;
Q_DECL_EXPORT int main(int argc, char **argv)
{
qmlRegisterType<TLDRApp>();
bb::data::DataSource::registerQmlTypes();
// this is where the server is started etc
TLDRApp app(argc, argv);
//Application app(argc, argv);
// localization support
QTranslator translator;
QString locale_string = QLocale().name();
QString filename = QString( "MyShows_%1" ).arg( locale_string );
if (translator.load(filename, "app/native/qm")) {
app.installTranslator( &translator );
}
// create the application pane object to init UI etc.
// new ApplicationUI(&app);
// we complete the transaction started in the app constructor and start the client event loop here
return Application::exec();
// when loop is exited the Application deletes the scene which deletes all its children (per qt rules for children)
}
mail.qml
Code:
import bb.cascades 1.0
import bb.data 1.0
import bb.system 1.0
Page {
titleBar: TitleBar {
id: myTitle
title: "My First App"
}
Container {
ImageView { // CoverImage - Poster
id: myPoster
imageSource: {
tldrApp.ImagePath("es"); // TESTING ONLY, IT DOES RETURN THE PROPER VALUE IN tldrapp.cpp
}
preferredWidth: 110.0
preferredHeight: 150.0
scalingMethod: ScalingMethod.AspectFit
}
ListView {
dataModel: dataModel
listItemComponents: [
ListItemComponent {
type: "item"
MyListView {}
}
]
}
attachedObjects: [
GroupDataModel {
id: dataModel
grouping: ItemGrouping.None
sortingKeys: ["DATETIMEFEED"]
},
DataSource {
id: dataSource
source: "URL TO XML FILE"
query: "/Feed/items/item"
type: DataSourceType.Xml
onDataLoaded: {
dataModel.clear();
var tempdata = new Array();
for (var i = data.length-1; i >= 0; i--) {
// Create a Date object for the publication Date (for easier presentation)
var newDate = new Date(Date.parse(data[i].DateTIMEFEED, "dd mmmm yyyy h:MM:ss o"));
tempdata[i] = data[i]
tempdata[i].Name= data[i].Name
tempdata[i].Description= data[i].Description
tempdata[i].Imagepath= data[i].Imagepath
// Set the date
tempdata[i].DATETIMEFEED= newDate;
}
// Finally insert the data in the dataModel and it will be presented in the list.
dataModel.insertList(tempdata)
}
}
]
onCreationCompleted: {
dataSource.load();
}
}
}
MyListView.QML
Code:
import bb.cascades 1.0
import bb.data 1.0
import bb.system 1.0
Container{
layout: DockLayout {
}
topPadding: 6.0
bottomPadding: 6.0
Divider {
id: myDivider
}
Container { //ListViewLayout
layout: AbsoluteLayout {
}
verticalAlignment: VerticalAlignment.Center
ImageView {
id: myPoster
imageSource: {
tldrApp.ImagePath(ListItemData.Imagepath); // NOTHING HAPPENS HERE
}
preferredWidth: 110.0
preferredHeight: 150.0
scalingMethod: ScalingMethod.AspectFit
layoutProperties: AbsoluteLayoutProperties {
positionY: 6.0
}
}
Label {
id: myName
text: {
tldrApp.ImagePath("TESTING"); // NOTHING HAPPENS HERE, SHOULD RETURN THE PATH AS IT DOES IN mail.qml
}
layoutProperties: AbsoluteLayoutProperties {
positionY: 5.0
positionX: 120.0
}
textStyle.fontSize: FontSize.PointValue
textStyle.fontSizeValue: 8.0
}
Label {
id: myDescription
text: ListItemData.Description
layoutProperties: AbsoluteLayoutProperties {
positionY: 55.0
positionX: 130.0
}
textFormat: TextFormat.Plain
textStyle.fontSizeValue: 6.0
visible: true
textStyle.fontSize: FontSize.PointValue
}
Label {
id: myDate
text: "Date: " + Qt.formatDate(ListItemData.DATETIMEFEED, "dddd, MMMM dd, yyyy")
layoutProperties: AbsoluteLayoutProperties {
positionY: 90.0
positionX: 130.0
}
textFormat: TextFormat.Plain
textStyle.fontSizeValue: 6.0
visible: true
textStyle.fontSize: FontSize.PointValue
}
}
}
tldrapp.h -> straight copy from Blackberry's samples, with one or two additions.
Code:
/* 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 RSSAPP_H_
#define RSSAPP_H_
#include <QVariant>
#include <bb/cascades/Application>
/**
* Main class of the app, has a few utility functions for parsing RSSfeeds for
* images and stripping out HTML.
*
* You will learn how to:
* - Download images asynchronously
* - Parse RSS
*/
class TLDRApp: public bb::cascades::Application
{
Q_OBJECT
public:
TLDRApp(int argc, char **argv);
virtual ~TLDRApp();
/*
* Utility function to strip html-formatting.
*
* @param htmlString The string that is going to be stripped.
*/
Q_INVOKABLE QString plainText(const QString htmlString);
Q_INVOKABLE QString ImagePath(const QString locateImage);
/*
* The RSS feed format has grown over the years, so we need to parse
* the data to find the images
*
* @param item Data item containing an RSS entry that is parsed for a suitable image
* @return A string with the image path return "" if no image was found
*/
Q_INVOKABLE QString findImage(const QVariant item);
};
#endif /* RSSAPP_H_ */
tldrapp.cpp -> again from Blackberry sample with a couple omissions.
Code:
/* 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.
*/
#include "tldrapp.h"
#include "netimagemanager.h"
#include "netimagetracker.h"
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/data/DataSource>
#include <bb/system/SystemDialog>
#include <QDir>
using namespace bb::cascades;
using namespace bb::data;
using namespace bb::system;
TLDRApp::TLDRApp(int argc, char **argv) :
Application(argc, argv)
{
//qmlRegisterType<TLDRApp>();
DataSource::registerQmlTypes();
// Create scene document from main.qml asset
// set parent to created document to ensure it exists for the whole application lifetime
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
qml->setContextProperty("tldrApp", this);
// create root object for the UI
AbstractPane *root = qml->createRootObject<AbstractPane>();
// set created root object as a scene
setScene(root);
}
TLDRApp::~TLDRApp()
{
}
QString TLDRApp::ImagePath(const QString locateImage)
{
QString path = "app/native/assets/images/NoImage.png";
QFile file("app/native/assets/images/NoImage.png");
if (file.exists()){
return "asset:///images/NoImage.png";
}
else{
return "not Here";
}
}