Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
Posts: 358
Registered: ‎04-13-2013
My Device: Z10
My Carrier: Telus
Accepted Solution

App crashes when I attach exposed Class

So i've been trying to figure out how to get the filepath link for my camera invoke.  I'm at the point where I've tried everything to no avail.  My most recent attempt was attaching the exposed Class from my source code into my QML.

 

in main.cpp:

using ::bb::cascades::Application;
// this allows us to write "Application"
// instead of "bb::cascades::Application"

void myMessageOutput(QtMsgType type, const char* msg) {
	Q_UNUSED(type);
   fprintf(stdout, "%s\n", msg);
   fflush(stdout);
}
// main() is the entry point of the application. It will be called by the
// operating system when you start the application. You should never call this
// yourself.
Q_DECL_EXPORT int main(int argc, char **argv)
{

	qmlRegisterType<bb::platform::RouteMapInvoker>("bb.platform", 1, 0, "RouteMapInvoker");
	    bb::data&colon;:DataSource::registerQmlTypes();
	    qmlRegisterType<bb::platform::LocationMapInvoker>("bb.platform", 1, 0, "LocationMapInvoker");
	    bb::data&colon;:DataSource::registerQmlTypes();
    // "Application" is the BB cascades class that handles interaction the
    // with BB10 operating system.
    Application app(argc, argv);

#ifndef QT_NO_DEBUG
   qInstallMsgHandler(myMessageOutput);
   #endif

    // Register this type so qml can refer to enums and other symbols
    // declared in the App class.
    qmlRegisterType<ApplicationUI>("Custom.lib", 1, 0, "ApplicationUI");

    // Create an instance of App on the stack. App's
    // constructor registers itself with Application object using setScene().
    // See app.cpp
    app.setCover(new ActiveFrame());
    ApplicationUI mainApp;

    // Start the application event loop (run-loop).
    return Application::exec();

    // When the loop is exited the Application deletes the scene which deletes
    // all its children (per Qt rules for children)
}

 ApplicationUI.hpp:

 

class ApplicationUI : public QObject
{
    // Classes that inherit from QObject must have the Q_OBJECT macro so
    // the meta-object compiler (MOC) can add supporting code to the application.
    Q_OBJECT

    Q_PROPERTY(bb::cascades::DataModel* dataModel READ dataModel CONSTANT)

public:

    // Describes the possible storage locations
    enum StorageLocations
    {
        StoreInQSettings, ///< objects are stored in QSettings
        StoreInFile       ///< objects are stored in custom files
    };

    // This allows the enum to be referred to in the qml file.
    // Note: the class also has to be registered using qmlRegisterType().
    // See the main.cpp file.
    Q_ENUMS(StorageLocations)

    // Creates a new App object
    ApplicationUI(QObject *parent = 0);

    // destroys the App object
    ~ApplicationUI();

    Q_INVOKABLE
    	void inviteUserToDownloadViaBBM();
    Q_INVOKABLE
    	void updatePersonalMessage(const QString &message);

        // Creates a new location object and saves it.
    Q_INVOKABLE bool addObject(const QString &name, const QString &description, const QString &datefield, const QString &lat, const QString &lon, const QString &categoryfield, const QString &mapurl, const QString &itempic);

    // Read all the objects from the selected storage location and
    // put them in the data model
    Q_INVOKABLE void refreshObjects();

    // Remove all the objects from the selected storage location.
    Q_INVOKABLE void clearObjects();

    // Change the first and last name of the location with the
    // provided id. Update the data model and storage.
    Q_INVOKABLE bool updateObject(const QString &id, const QString &name, const QString &description, const QString &datefield, const QString &lat, const QString &lon, const QString &categoryfield, const QString &mapurl, const QString &itempic);

    // Delete the location with the given id from the selected storage location.
    Q_INVOKABLE bool deleteObject(const QString &id);

    // Change the location we're using for the data, and
    // refresh the list.
    Q_INVOKABLE void setStorageLocation(StorageLocations strLocation);

        Q_INVOKABLE void addPinAtCurrentMapCenter();
        Q_INVOKABLE void clearPins();
        Q_INVOKABLE void updateDeviceLocation(double lat, double lon);
        Q_INVOKABLE	QString getValueFor(const QString &objectName, const QString &defaultValue);
        Q_INVOKABLE void saveValueFor(const QString &objectName, const QString &inputValue);
        Q_INVOKABLE void InvokeCamera();
        Q_INVOKABLE void InvokeSettings();
        Q_INVOKABLE void InvokeImageViewer(const QString &urlPic);

        public slots:
        void childCardDone(const bb::system::CardDoneMessage &message);

        signals:
        void cameraCaptureCompleted(const QString &imageLink);
//        void filterChanged();

........

  in my ApplicationUI.cpp

 

ApplicationUI::ApplicationUI(QObject *parent)
    : QObject(parent)
    , m_lastCustomerID(0)
    , m_storageLocation(StoreInQSettings)
    , m_storage(new SettingsStorage)


{

	// prepare the localization
	    m_pTranslator = new QTranslator(this);
	    m_pLocaleHandler = new LocaleHandler(this);
	    invokeManager = new bb::system::InvokeManager();
	    invokeManager->setParent(this);

	    if(!QObject::connect(m_pLocaleHandler,
	        SIGNAL(systemLanguageChanged()),
	        this,
	        SLOT(onSystemLanguageChanged()))) {
	        // This is an abnormal situation! Something went wrong!
	        // Add own code to recover here
	        qWarning() << "Recovering from a failed connect()";
	    }

	    connect(invokeManager,
	    SIGNAL(childCardDone(const bb::system::CardDoneMessage&)), this,
	    SLOT(childCardDone(const bb::system::CardDoneMessage&)));

	    // initial load
	    onSystemLanguageChanged();

    // Initialize the data model before the UI is loaded
    // and built so its ready to be used.
    initDataModel();

//    qmlRegisterType<App>("uri",1,0,"App");

    QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
    qml->setContextProperty("_app", this);



    AbstractPane *root = qml->createRootObject<AbstractPane>();

.....


void ApplicationUI::InvokeCamera()
{
	bb::system::InvokeManager manager;
	bb::system::InvokeRequest request;
	request.setTarget("sys.camera.card");
	request.setAction("bb.action.CAPTURE ");
	request.setMimeType("image/jpeg");
	InvokeTargetReply *targetReply = manager.invoke(request);

}

void ApplicationUI::childCardDone(const bb::system::CardDoneMessage &message)
{
	QString imageLink;
	if (message.reason() == "done") {

		imageLink = "file://" + message.data();
	}
	qDebug() << message.reason() << "\n";
	qDebug() << message.dataType() << "\n";
	qDebug() << "file://" + message.data() << "\n";

	emit cameraCaptureCompleted(imageLink);
}

 

 

in my QML:

 

import bb.cascades 1.0
import Custom.lib 1.0

Sheet{

Page{

Container{

Label{
id: itemPic
} Button{ onClicked: { _app.InvokeCamera() } } } attachedObjects: [ ApplicationUI {
onCamerCapturedCompleted: {

itemPic.setText(imageLink)

}
} ]
} }

 As soon as I attach the class the app will not start and crash,  if I edit it out it's fine.

Developer
Posts: 6,152
Registered: ‎07-05-2012
My Device: Playbook, Dev Alpha C, Z10 LE, Z30
My Carrier: Orange

Re: App crashes when I attach exposed Class

I don't thinl you can register the applicationui and what would be the point anyway as only a single instance can be run.

 

Do you just want to access variables and functions within your QML?


If you've been helped click on Like Button, if you've been saved buy the app. :smileyhappy:

Developer of stokLocker, Sympatico and Super Sentences.
Developer
Posts: 6,152
Registered: ‎07-05-2012
My Device: Playbook, Dev Alpha C, Z10 LE, Z30
My Carrier: Orange

Re: App crashes when I attach exposed Class

Instead pass the AppInstance as a property and use the Q_ENUMS macro.


If you've been helped click on Like Button, if you've been saved buy the app. :smileyhappy:

Developer of stokLocker, Sympatico and Super Sentences.
Developer
Posts: 358
Registered: ‎04-13-2013
My Device: Z10
My Carrier: Telus

Re: App crashes when I attach exposed Class

like this?

 

void ApplicationUI::childCardDone(const bb::system::CardDoneMessage &message)
{
  QmlDocument *qml = QmlDocument::create("asset:///main.qml")
    		.property("_app", this)
                 .property("passedProperty", imageLink);
    		.parent(this);


	QString imageLink;
	if (message.reason() == "done") {

		imageLink = "file://" + message.data();
	}
	qDebug() << message.reason() << "\n";
	qDebug() << message.dataType() << "\n";
	qDebug() << "file://" + message.data() << "\n";

	emit cameraCaptureCompleted(imageLink);
}

 

Developer
Posts: 1,523
Registered: ‎12-18-2012
My Device: Z30, Z10 LE, DevAlpha C, PlayBook

Re: App crashes when I attach exposed Class

Hi,

ApplicationUI instance is already exported to QML as _app. A possible approach is connecting the signal to a JS function:

 

Sheet
{
  onCreationCompleted: {
    _app.cameraCaptureCompleted.connect(captureCompleted)
  }
  
  function captureCompleted(imageLink) {
    console.log("imageLink: " + imageLink)
  }
  ...

}

Using Qt Quick's 'Connection' element is another option.

 

This code should be removed (it creates a second instance of ApplicationUI, which likely wasn't intended):

 

qmlRegisterType<ApplicationUI>("Custom.lib", 1, 0, "ApplicationUI");

...

attachedObjects: [
ApplicationUI {
onCamerCapturedCompleted: {
itemPic.setText(imageLink)
}

 


Andrey Fidrya, @zmeyc on twitter
Developer
Posts: 358
Registered: ‎04-13-2013
My Device: Z10
My Carrier: Telus

Re: App crashes when I attach exposed Class

Thank you!  That connected my function!  unfortunately it just shows "imageLink:  "  meaning it's not actually showing the filepath.  Is there something wrong without how I setup the emit?

 

void ApplicationUI::childCardDone(const bb::system::CardDoneMessage &message)
{
	QString imageLink;
	if (message.reason() == "done") {

		imageLink = "file://" + message.data();
	}
	qDebug() << message.reason() << "\n";
	qDebug() << message.dataType() << "\n";
	qDebug() << "file://" + message.data() << "\n";

	emit cameraCaptureCompleted(imageLink);
}

 

public slots:
        void childCardDone(const bb::system::CardDoneMessage &message);

        signals:
        void cameraCaptureCompleted(const QString &imageLink);
//        void filterChanged();

 

I'm invoking the camera from a button on a sheet and want to save the reply filepath in my data model when the Save action item is triggered.

Sheet {
            id: addSheet
            Page {
                onCreationCompleted: {
                    _app.cameraCaptureCompleted.connect(captureCompleted)
                }
                function captureCompleted(imageLink) {
                    console.log("imageLink: " + imageLink)
                }
                id: addPage
                titleBar: TitleBar {
                    id: addBar
                    title: qsTr("Add") + Retranslate.onLanguageChanged
                    visibility: ChromeVisibility.Visible
                    
                    dismissAction: ActionItem {
                        title: qsTr("Cancel") + Retranslate.onLanguageChanged
                        onTriggered: {
                            // Hide the Sheet.
                            addSheet.close()
                            name.text = ""
                            description.text = ""
                            categorySelect.setSelectedOption(miscellaneousoption)
                        }
                    }
                    acceptAction: ActionItem {
                        title: qsTr("Save") + Retranslate.onLanguageChanged
                        attachedObjects: [
                            SystemToast {
                                id: saveToast
                                body: qsTr("Saved") + Retranslate.onLanguageChanged
                            }
                        ]
                        onTriggered: {
 _app.addObject(name.text, description.text, datefield.text, lat.text, lon.text, categorySelect.selectedOption.text, mapview.url(), <<SAVE FILEPATH HERE>>);
                            addSheet.close()
                            saveToast.show()

                        }
                    }
                }

.....

                            Container {
                                
                                Button {
                                    preferredWidth: 300
                                    imageSource: "asset:///images/ic_camera.png"
                                    onClicked: {
					_app.InvokeCamera()   
                                    }
                                } 
                            }

 

Developer
Posts: 1,523
Registered: ‎12-18-2012
My Device: Z30, Z10 LE, DevAlpha C, PlayBook

Re: App crashes when I attach exposed Class

Could you try simplifying the function for testing:

 

void ApplicationUI::childCardDone(const bb::system::CardDoneMessage &message)
{
	QString imageLink = "Test";

	emit cameraCaptureCompleted(imageLink);
}

 If the value is succesfully retrieved, it can be passed further using a property:

 

Sheet {
  property string url

  ...

function captureCompleted(imageLink) { url = imageLink } ... _app.addObject(name.text, description.text, datefield.text, lat.text, lon.text, categorySelect.selectedOption.text, mapview.url(), url);

 


Andrey Fidrya, @zmeyc on twitter
Developer
Posts: 358
Registered: ‎04-13-2013
My Device: Z10
My Carrier: Telus

Re: App crashes when I attach exposed Class

terminal says "can't find variable: url"

 

Sheet{
Page {
                property string url
                onCreationCompleted: {
                    _app.cameraCaptureCompleted.connect(captureCompleted)
                }
                function captureCompleted(imageLink) {
                    url = imageLink
                }

....

onTriggered: {

_app.addObject(name.text, description.text, datefield.text, lat.text, lon.text, categorySelect.selectedOption.text, mapview.url(), url);

}

 

cpp:

 

void ApplicationUI::childCardDone(const bb::system::CardDoneMessage &message)
{
	QString imageLink = "test";

	emit cameraCaptureCompleted(imageLink);
}

 

Developer
Posts: 358
Registered: ‎04-13-2013
My Device: Z10
My Carrier: Telus

Re: App crashes when I attach exposed Class

When I do :

function captureCompleted(imageLink) {
                    console.log(imageLink)
                }

 it igves me the result

Developer
Posts: 358
Registered: ‎04-13-2013
My Device: Z10
My Carrier: Telus

Re: App crashes when I attach exposed Class

got it to work like this:

 

acceptAction: ActionItem {
                        title: qsTr("Save") + Retranslate.onLanguageChanged
                        attachedObjects: [
                            SystemToast {
                                id: saveToast
                                body: qsTr("Saved") + Retranslate.onLanguageChanged
                            }
                        ]
                        property string url
                        onCreationCompleted: {
                            _app.cameraCaptureCompleted.connect(captureCompleted)
                        }
                        function captureCompleted(imageLink) {
                            url = imageLink
                            console.log(imageLink)
                        }
                        onTriggered: {
_app.addObject(name.text, description.text, datefield.text, lat.text, lon.text, categorySelect.selectedOption.text, mapview.url(), url);
}