Expose properties c ++ to qml

While browsing the BB developer documentation, I came across this example. Here, I do not specifically code qml.

Button {
            id: myButton
            text: "Increase the value"
            onClicked: {
                myCppObject.valueChanged.connect(myButton.onCppValueChanged);
                myCppObject.value = myCppObject.value + 1;
            }
            function onCppValueChanged(val) {                console.debug(val);
                myButton.text = "Set value to " + (val + 1);
            }
        }

First of all, in code above

  1. signal "valueChanged" accept a single parameter and here I get no notion of 'connect '.
  2. function 'onCppValueChanged' is called worthless, how the hell it is possible to pass. And also if it is possible in javascript that how the value of the 'val' becomes 21 I tried printing the value to the console is 21. Please clarify my questions ASAP

either connect feature connects signal which is defined in CPC (valueChanged (int)) connects to our housing located in our qml (onCppValueChanged (val))

Am I wrong?

Tags: BlackBerry Developers

Similar Questions

  • QML how to expose properties of the component.

    Hello

    Qml how we can expose the properties of a component.

    for example

    TextField component has a properties such as hintText, id etc. same thing we exhibit in eclipse with cntr + space but I don't know how to expose it in qml.

    Windows Goto-> to see the view-> QML properties

  • Application crashes when I expose C++ groupDataModel in qml

    Hello world

    in my application, I have discovered in a container list. When I click on one of these items in the list another page is loaded. The user interface is qml. It works very well. But now I want to add data to the page. If I do it crashes without warning or error.

    Here is the part of the code inportant:

    // Main.qml[...]onTriggered: {
                        var selectedItem = dataModel.data(indexPath);
    
                        var page = Qt.app.doLoadPageDetails();
    
                        navigationPane.push(page);
                    }[...]
    

    and here's what the doLoadPageDetails function defined in C++:

    // applicationui.cppPage* ApplicationUI::doLoadPageDetails(){    QmlDocument *qml = QmlDocument::create("asset:///PageDetails/PageDetails.qml").parent(this);
        qml->setContextProperty("app", this);
    
        Page* newPage = qml->createRootObject();
    
        // Create root object for the UI
         AbstractPane *root = qml->createRootObject();
    
         GroupDataModel *contactModel = new GroupDataModel;
            // ----> here I fill the data model with contacts
    
        // Connect to list view and update model
         ListView *contactListView = root->findChild("listContacts");
    
        contactListView->setDataModel(contactModel); <----- here my app crashes
    
        return newPage;
    }
    
    Page{
    ...
      Container{
    ...
        Container{
    ...
          ListView{
    ...
            id: listContacts
            dataModel: groupDataModel
            listItemComponents: [
              ListItemComponent {
                StandardListItem {
                  title: ListItemData.personName
                  description: ListItemData.mail
                  status: ListItemData.more
    ...
                }
              }
            ]
          }
        }
      }
    }
    

    I discovered by messages from debugging the accident happens when I want to inject the data to my page in qml model.

    Another point of my application, it works. But I can't know where the differences are. The only difference that I see so far is that in the other page ListView is inside a container. Not like here the ListView is inside a container which is once again within a container.

    Has anyone an idea what I can try to understand what is the cause of this accident? Without any error message, it is difficult to find the answer.

    Found the solution.

    I forgot to set the objectname in the ListView.

    ...ListView{  id: listContacts
      objectName: "listContacts"}
    

    I thought id would be the link between qml and C++.

  • Object of type complex C++ exposing to QML

    In a C++ file, I have an object of the typeQList *, which is supposed to be a two dimension an array of strings.

    How to expose this object to QML, I know how I'll be able to navigate / access its functions in QML?

    Currently, in C++, I am able to do this:

    // this will display the QString value in the Console
    qDebug() << "test: " << entries->at(0).at(0);
    

    I really have to do, is to send a two dimension array of strings of C++ to QML. I do this too complicated? Is there another way to solve this problem?

    Solution here: objects exhibition complex C++ Qt QML

  • c ++ bool qml undefined when exposedwith ContextProperty

    In an attempt to circumvent the problem of PickerItemComponent not been able to access what anyone outside himself, I exposed a bool for QML (my application has a Bool QML, called compactMode, long story), now since I can't access that bool compactMode I tried to expose a c ++ one like this:

    public:
    
        bool compactModeGlobal;
    
        QDeclarativeEngine *engine = QmlDocument::defaultDeclarativeEngine();
        QDeclarativeContext *rootContext = engine->rootContext();
    
        rootContext->setContextProperty("compactModeGlobal", compactModeGlobal);
    

    It gives me the warning of "Member"compactModeGlobal"has not been initialized in the constructor.

    That, of course, it won't let me spend this compactModeGlobal bool QML

    I missed something important it?

    In general in the ApplicationUI constructor, you would report the properties that you want to expose from C++, using Q_PROPERTY and QObject ceremony associated with the functions of getter/setter/broadcasting signal and set a context property on your document main qml like this:

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

    where "this" in the call of setContextProperty() refers to the ApplicationUI object.

    Edit: So, in your doc QML, you acceding C++ properties using:

    SomeQMLComponent {
        someQMLProperty:  _app.someCppProperty
    }
    
  • JS function as a type of page in QML property

    Hi all

    I'm trying to create useful js 'class' for my blackberry application and save here some information about qml object here is the example of such file js:

    /* * my js */
    
    function Utils(devInfo){ this.devInfo = devInfo; this.text = "test text";
    
     this.getInfo = function(){ return this.text; };}
    

    I want to group some utils functions here and use this js in qml file object, but I don't want to create "Utils" every time, I would like to have a single instance of page qml. I tried to use properties:

    import bb.cascades 1.3
    import com.example.bb10_samples_states 1.0
    import "myscripts.js" as Scripts
    
    Page {
        property variant utils : new Scripts.Utils(deviceInfo)
    
        Container {
            Label {
                id: myLabel
                text: "Hello World"
            }
    
            onTouch: {
                var newLabeltext = utils.getInfo(); // freezing
                myLabel.text = newLabeltext;
            }
        }
    
        attachedObjects: [
            DevInfo{
                id: deviceInfo
            }
        ]
    }
    

    * DevInfo is registered object c ++

    I got the following in the notecard event error message:

    "asset:///main.qml:15: TypeError: result of expression 'utils.getInfo' [[object Object]] is not a function."

    If I do not use the property and only with variable work, everything is ok. The following code works correctly:

    import bb.cascades 1.3
    import com.example.bb10_samples_states 1.0
    import "myscripts.js" as Scripts
    
    Page {
        //property variant utils : new Scripts.Utils(deviceInfo)
    
        Container {
            Label {
                id: myLabel
                text: "Hello World"
            }
    
            onTouch: {
                var utils = new Scripts.Utils(deviceInfo);
    
                var newLabeltext = utils.getInfo();
                myLabel.text = newLabeltext;
            }
        }
    
        attachedObjects: [
            DevInfo{
                id: deviceInfo
            }
        ]
    }
    

    In general, I don't know where I can store object js in qml page to access my functions utils without need to create each time. Any ideas?

    I think I found the answer

    According to this link, there is no global js object and every instance of component QML has own unique copy resources imported from JS:

    ...

    Code-Behind implementation resources

    Most of the JavaScript files imported into a document QML are implementations with State of the QML importation document. In these cases, each instance of the QML object type defined in the document requires a separate copy of the JavaScript and State objects to behave properly.

    The default behavior when importing the JavaScript files must provide a unique and isolated copy for each instance of the QML component. If this JavaScript file any resources or modules with a statement .import, its code will be executed in the same scope as the instance of the QML component and therefore can access and manipulate objects and properties declared in the QML component. Otherwise, it will have its own unique scope, and the objects and properties of the QML component should be passed to the JavaScript file as parameters functions if they are required.

    ...

    http://Qt-project.org/doc/Qt-5/qtqml-JavaScript-resources.html

    So it seems there is no need to implement the model of sigleton or store JS resources in the QML document. I changed my code as follows:

    /**
     * js
     */
    var utils = {
      devInfo : null
    };
    
    function init(deviceInfo){
      utils.devInfo = deviceInfo;
    };
    
    function getText(){
      return utils.devInfo + " done.";
    };
    

    and qml:

    import bb.cascades 1.3
    import com.example.bb10_samples_states 1.0
    
    import "myscripts.js" as Scripts
    
    Page {
        Container {
            Label {
                id: myLabel
                text: "Hello World"
            }
    
            onCreationCompleted: {
                Scripts.init(deviceInfo);
            }
    
            onTouch: {
                myLabel.text = Scripts.getText("Tra-ta-ta");
            }
        }
    
        attachedObjects: [
            DevInfo{
                id: deviceInfo
            }
        ]
    }
    

    It works fine - I can store information in the variable 'utils' and work with qml js objects. Hope so, it will help someone

  • Update QML component c++

    Hello

    I was following the situation. Let's say I have a main QML file that is called from C++ as follows:

    ShareTheMatch::ShareTheMatch(bb::cascades::Application *app)
    : QObject(app)
    {
        // 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);
    
        // create root object for the UI
        AbstractPane *root = qml->createRootObject();
    
        // Expose networking instance to QML so that from QML it is possible
        // to make queries to the network and the server
        NetworkManager *networkObject = new NetworkManager();
        qml->setContextProperty("networkObject", networkObject);
    
        // set created root object as a scene
        app->setScene(root);
    }
    

    Now, on the main.qml file, the user can do various activities, for example to navigate to a new .qml file.

    Now, imagine a user has clicked a button on the file main.qml which he redirected a qml file, called

    SecondDialog.qml. my problem is the following. Code C++ (see above), I want to be able to update

    a component that is located on the SecondDialog.qml - how is possible to do this?

    PS. I know not how I'd be able to do that if I were to update a component that was on the file main.qml (e.. g, using the findChild method), but I do not know how to proceed in the case of SecondDialog.qml (partially because she is recalled in another qml file). How to get there?

    Any help greately appreciated.

    set an object name

    Button{
    id: myButton
    objectName: "secondPageButton"
    }
    
    Button *newButton = bb::cascades::Application::instance()->findChild("secondPageButton");
    
  • load the HTML to qml

    Hello

    what I want to do is to dynamically load the HTML an application Web layout. Which means that I generate an HTML fill it with a string and then put this with some style options in the qml Web view option.

    I am new to BlackBerry applications development and I do not know how to start here. Can anyone give me a tip?

    This is really another question and which I think needs you to play with the creation of your own custom control classes until I understand the concept.

    However, the key will be;

    Create a class derived from QObject

    Add a QProperty something like myHtml

    Write dynamic html code in the class

    Expose the class to QML

    Include your library in the QML page

    Add your QObject class myHtml property to property html WebView

    It seems probably complicated at first, but there are many examples in the samples, so I suggest you download a few of these and work with their understanding.

  • connect the current coords in qml to a url on the CPP

    Hi, I have a url on CPP file to analyze my weather data, but the current location its on my main qml trought PositionSource attachedObject and I save in a property string latitude and a longitude of chain ownership, how can I use it on my url in the file c

    ExternalIP::getWeatherdata() Sub
    {
    const QUrl url ("http://api.openweathermap.org/data/2.5/weather?lat=22.2553&lon=-97.8686&units=metric");
    QNetworkRequest request (url);

    Check the settings of the application
    If (AppSettings::isUsingFarenheit()) {}
    request.setUrl (QUrl ("http://api.openweathermap.org/data/2.5/weather?lat=22.2553&lon=-97.8686&units=imperial"));

    }

    // Your function in Header file
    
    public:
        Q_INVOKABLE ....getWeather(const QString latitude, const QString longtitude);
    
    // cpp
    ...getWeather(const QString latitude, const QString longtitude)
    {
        QUrl url(QString("http://....%1%2").arg(latitude).arg(longtitude));
        .....
    }
    
    // Then expose your class to QML
    
    QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this)                                .property("MyClass", this);
    

    And after that, you can call the function of QML

    PositionSource{
        .....
        ended: MyClass.getWeather(latitude, longtitude)
    }
    

    It may be useful

    For more information

    https://developer.BlackBerry.com/native/documentation/Cascades/dev/integrating_cpp_qml/#usingcclasse...

  • including a QML file?

    Hey new to waterfalls, I try to include a qml file in my main.qml with the following...

    TabbedPane {}

    Tab {}

    Title: 'corner '.

    imageSource: "asset:///icons/coin.png."

    Content: part {}

    }

    }

    }

    When I try to deploy the project to my phone, it's just has a BlackBerry 10 logo and a black screen.

    Hello

    'content' property is tiny. It is also a property by default so write ' content: {FileName} "is not necessary, simply write"FileName {} ".

    If you have FileName.qml where the page is defined:

    Page {
      ...page content...
    }
    

    It can be used as follows (by removing the file extension):

    TabbedPane {
        Tab {
            title : "tab1"
            description : "This is only shown in the side bar"
            imageSource : "tab.png"
            FileName {          // optionally override some properties here        }
        }
    }
    

    QML types should begin with capital letter.

  • Cannot call QML C++ objects

    I tried to check the active frame example since the blackberry official site https://developer.blackberry.com/native/documentation/cascades/ui/active_frames/ and it worked perfectly. But when I tried to integrate it into my app, it showed "cannot find variable activeFrame" warning.

    I know, I have to expose the object of QML with setContextProperty, I did it but in order to use nothing. I use other objects incorporated as batteryinfo (of class BatteryInfo) and all this without any issue at all, either.

    The problem has also occurred when I tried to implement Qsettings in my application and create the reference to the object to use in QML as _myapp and once again had WARNING 'cannot find variable _myapp' in the console.

    The examples perform very well when I run them independently as a stand-alone application. The problem creeps when I integrate and run it in my application!

    All thoughts, which could possible could have gone wrong?

    You seem to be loading your main qml twice, it must be done in the applicationui.

    But to be honest that I fight to read this, please can implement you the suggested changes above, I did?

  • Changing variables of C++ QML UI (json source and sorting keys)

    Hello

    I have a tabbed two tabbed pane. I want to fill each tab with a dfifferent JSON (list (not XML). I managed to fill the first tab with the first json file... following the example of application stampcollector. All the UI is QML but JSON loading and groupdatamodel of adjustment is done in C++.

    1. now I want to fill the tab page of the 2nd with another JSON list. How can I go about it? Create a new class or can I change the JSON source when the 2nd tab fires?

    2 just like in the application of stampcollecctor, I use sort keys. I have a few elements of the action in QML, that when you press on, I want that sort of change lists. So let's say that the first action to sort A - Z, the second action Z - A, the third of the population, action action 4th by area.  How to access and change the sort key?

     

    3. is there in any case to sort alphabetically in reverse order, from Z - A?

    Code I have so far is below... just no idea where to start...

    hand. QML

    import bb.cascades 1.0
    
    TabbedPane {
        id: mainTabPage
        showTabsOnActionBar: true
    
        // Country Tab
        Tab {
            title: "Countries"
            NavigationPane {
                id: countryTabNav
                property variant _countryView;
                Page {
                    Container {
                        ListView {
                            id: countryList
                            objectName: "countryList"
                            listItemComponents: [
                                ListItemComponent {
                                    type: "listItem"
                                    StandardListItem {
                                        title: ListItemData.country
                                        status: ListItemData.population
                                        description: ListItemData.capital
                                    }
                                }
                            ]
    
                            onTriggered: {
                                var chosenItem = dataModel.data(indexPath);
                                _countryView = chosenItem;
                                countryTabNav.deprecatedPushQmlByString("countryDetail.qml");
                            }
                        }
    
                        //-- define tab content here
                        layout: StackLayout {
                        }
    
                    }
                }
            }
        }
    }
    

    App.cpp

    #include "app.hpp"
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    using namespace bb::cascades;
    using namespace bb::data;
    
    App::App() {
        QmlDocument *qml = QmlDocument::create("main.qml");
        //-- setContextProperty expose C++ object in QML as an variable
        //-- uncomment next line to introduce 'this' object to QML name space as an 'app' variable
        //qml->setContextProperty("app", this);
    
        AbstractPane *root = qml->createRootNode();
    
        // ListView Model
        ListView *countryList = root->findChild("countryList");
        setupCountryListModel(countryList);
    
        Application::setScene(root);
    }
    
    void App::setupCountryListModel(ListView *countryList) {
        JsonDataAccess jda;
        QVariantList mainList = jda.load("app/native/assets/countries.json").value();
    
        if (jda.hasError()) {
            bb::data::DataAccessError error = jda.error();
            qDebug() << "JSON loading error: " << error.errorType() << ": "
                    << error.errorMessage();
            return;
        }
    
        GroupDataModel *countryModel = new GroupDataModel(QStringList() << "country");
        countryModel->setParent(this);
        countryModel->insertList(mainList);
        countryModel->setGrouping(ItemGrouping::ByFullValue);
    
        countryList->setDataModel(countryModel);
    
    }
    

    App.HPP

    #ifndef APP_H
    #define APP_H
    
    #include 
    #include 
    
    using namespace bb::cascades;
    
    namespace bb
    {
        namespace cascades
        {
            class ListView;
        }
    }
    
    /*!
     * @brief Application GUI object
     */
    class App : public QObject
    {
        Q_OBJECT
    public:
        App();
    
    private:
        void setupCountryListModel(ListView *countryList);
    };
    
    #endif // ifndef APP_H
    

    1. you will need to duplicate what you did for the other tab.  Check out weatherguesser which has a bunch of tabs and datamodels.

    2. order groupdata model page

    https://developer.BlackBerry.com/Cascades/reference/bb__cascades__groupdatamodel.html#setsortingkeys

    Try:

    countryModel->setSortingKeys())

    3.

    countryModel-> setsortedascending (false)

  • Native of filebrowse using and the cascading Save dialog box

    In my application I need to open file and file save dialog box when a specific button is clicked. I looked at the docs of stunts, but I found that the native options. Tried the native alert dialog, change of filebrowse dialog type. It displays well on Simulator, but could not get any output file that will be used in the Qt code.

    I pass these parameters

    int * num = NULL;

    char * folder [1024];
    dialog_update (alert_dialog);

    to dialog_event_get_filebrowse_filepaths(event,file,num), but it always returns BPS_FAILURE.

    In addition, access_shared is present in the bar-descriptor

    Here is my code:

    //slot function
    void App::fileOpen(){
        //===========================
            dialog_instance_t alert_dialog = 0;
    
            bps_initialize();
    
            dialog_request_events(0);    //0 indicates that all events are requested
    
            if (dialog_create_filebrowse(&alert_dialog) != BPS_SUCCESS) {
                        fprintf(stderr, "Failed to create alert dialog.");
                        return ;
                }
                const char* extensions[] = {"*.*","*.jpg","*.jpeg","*.mp3","*.wav","*.mp4","*.txt","*.doc","*.pdf"};
                int items = 9;
                if(dialog_set_filebrowse_filter(alert_dialog, extensions,items) != BPS_SUCCESS){
                    fprintf(stderr, "Failed to set alert dialog message text.");
                            dialog_destroy(alert_dialog);
                           alert_dialog = 0;
                           return ;
                }
               if( dialog_set_filebrowse_multiselect(alert_dialog,FALSE)!=BPS_SUCCESS){
                   fprintf(stderr, "Failed to set alert dialog message text.");
                                dialog_destroy(alert_dialog);
                               alert_dialog = 0;
                               return ;
               }
    
            if (dialog_show(alert_dialog) != BPS_SUCCESS) {
                fprintf(stderr, "Failed to show alert dialog.");
                dialog_destroy(alert_dialog);
                alert_dialog = 0;
                return ;
            }
    
            int shutdown =0;
            while (!shutdown) {
                bps_event_t *event = NULL;
                bps_get_event(&event, -1);    // -1 means that the function waits
                                              // for an event before returning
    
                if (event) {
                    if (bps_event_get_domain(event) == dialog_get_domain()) {
    
                        int selectedIndex =
                            dialog_event_get_selected_index(event);
                        const char* label =
                            dialog_event_get_selected_label(event);
                        const char* context =
                            dialog_event_get_selected_context(event);
    
                        char **fileArray[]={};
                        int *numFiles = NULL;
                       //
                              if(selectedIndex == 0){
           shutdown = 1;//user press the cancel button on dialog; close the dialog
       }
       else if(selectedIndex == 1){
           if(dialog_event_get_filebrowse_filepaths(event,file,num)!=BPS_SUCCESS){
           fprintf(stderr,"File open fail");
       }
       else{
    
    //debug purposes
           fprintf(stderr,"File array: %d/n",sizeof(file)*1024);
               fprintf(stderr,"Num files: %n",num);
               //fprintf(stderr,"Files int: %d",files);
       }
    
       }
                    }
                }
            }
    
            if (alert_dialog) {
                dialog_destroy(alert_dialog);
            }
            //===========================
    }
    

    Native Subforums have no useful information on this subject. Any help is greatly appreciated

    Hello again, here's the example as promised.

    To use the native filebrowse dialog box, the native code must run in its own thread to prevent the user interface in the Cascades to block. This is achieved by encapsulating all the dialog box code in a class derived from QThread.  The class I wrote is called FileBrowseDialog

    FileBrowseDialog.hpp

    #ifndef FILEBROWSEDIALOG_HPP_
    #define FILEBROWSEDIALOG_HPP_
    
    #include 
    #include 
    #include 
    
    /*
     * The file browse dialog displays a dialog to browse and select
     * files from shared folders on the system.
     */
    class FileBrowseDialog : public QThread
    {
        Q_OBJECT
    
        /*
         * QML property to allow multiple selection
         */
        Q_PROPERTY(bool multiselect READ getMultiSelect WRITE setMultiSelect)
    
        /*
         * QML property to read the selected filenames
         */
        Q_PROPERTY(QVariant filepaths READ getFilePaths)
    
        /*
         * QML property to set or get the file filters. This is an
         * list array variant.
         */
        Q_PROPERTY(QVariant filters READ getFilters WRITE setFilters)
    public:
        /*
         * Ctor and Dtor
         */
        FileBrowseDialog(QObject* parent = 0);
        virtual ~FileBrowseDialog();
    
        /*
         * Exposed to QML to start the run loop which creates and displays the dialog.
         * The dialog is shown until a button is clicked.
         */
        Q_INVOKABLE void show();
    
    public:
        /*
         * Getter for the selected filenames QML property
         */
        QVariant getFilePaths() const;
    
        /*
         * Setter and Getter for the filters QML property
         */
        QVariant getFilters() const;
        void setFilters(QVariant const& value);
    
        /*
         * Getter and Setter for the multiselect QML property
         */
        bool getMultiSelect() const;
        void setMultiSelect(bool value);
    
    signals:
        /*
         * Signal emitted when the OK button has been clicked on the browse dialog
         * The OK button is not enabled unless a file is selected
         */
        void selectionCompleted();
    
        /*
         * Signal emitted when the cancel button has been clicked on the browse dialog
         */
        void selectionCancelled();
    
    protected:
        /*
         * Implements the run loop. Dialog stays open until a button is clicked.
         */
        virtual void run();
    
    protected:
        dialog_instance_t m_dialog;
        bool m_multiSelect;
        QVariantList m_filePaths;
        QVariantList m_filters;
    };
    
    #endif /* FILEBROWSEDIALOG_HPP_ */
    

    FileBrowseDialog.cpp

    #include "FileBrowseDialog.hpp"
    #include 
    #include 
    
    FileBrowseDialog::FileBrowseDialog(QObject* parent)
        : QThread(parent)
        , m_multiSelect(false)
    {
        m_filters.push_back(QString("*.*"));
    }
    
    FileBrowseDialog::~FileBrowseDialog()
    {
    }
    
    void FileBrowseDialog::show()
    {
        if (!isRunning())
        {
            m_filePaths.clear();
            start();
        }
    }
    
    QVariant FileBrowseDialog::getFilePaths() const
    {
        return m_filePaths;
    }
    
    bool FileBrowseDialog::getMultiSelect() const
    {
        return m_multiSelect;
    }
    
    void FileBrowseDialog::setMultiSelect(bool value)
    {
        m_multiSelect = value;
    }
    
    QVariant FileBrowseDialog::getFilters() const
    {
        return m_filters;
    }
    
    void FileBrowseDialog::setFilters(QVariant const& value)
    {
        m_filters = value.toList();
        qDebug() << "filter count: " << m_filters.count();
    }
    
    void FileBrowseDialog::run()
    {
        bps_initialize();
    
        //request all dialog events
        dialog_request_events(0);
        if (dialog_create_filebrowse(&m_dialog) != BPS_SUCCESS)
        {
            qDebug() << "Failed to create file browse dialog.";
            emit selectionCancelled();
            return;
        }
    
        //set the selection filters
        if (m_filters.count() > 0)
        {
            char** ext = (char**)new char[m_filters.count()*sizeof(char*)];
            int i = 0;
            for (QVariantList::iterator it = m_filters.begin(); it != m_filters.end(); ++it, ++i)
            {
                QString filter = it->toString();
                if (!filter.trimmed().isEmpty())
                {
                    int length = (filter.length() + 1) * sizeof(char);
                    ext[i] = new char[length];
                    strncpy(ext[i], filter.toAscii(), length);
                }
            }
            if (dialog_set_filebrowse_filter(m_dialog, (const char**)ext, m_filters.count()) != BPS_SUCCESS)
            {
                qDebug() << "unable to set file browse dialog extensions";
            }
            for (i = 0; i < m_filters.count(); i++)
            {
                delete ext[i];
            }
            delete ext;
        }
    
        if (dialog_show(m_dialog) != BPS_SUCCESS)
        {
            qDebug() << "Failed to show file browse dialog.";
            dialog_destroy(m_dialog);
            m_dialog = 0;
            emit selectionCancelled();
            return;
        }
    
        bool shutdown = false;
        while (!shutdown)
        {
            bps_event_t* event = NULL;
            bps_get_event(&event, -1);    // -1 means that the function waits
            // for an event before returning
    
            if (event)
            {
                if (bps_event_get_domain(event) == dialog_get_domain())
                {
                    //0=ok, 1=cancel
                    int selectedIndex = dialog_event_get_selected_index(event);
    
                    if (selectedIndex == 1)
                    {
                        int count;
                        char** filepaths;
                        if (BPS_SUCCESS == dialog_event_get_filebrowse_filepaths(event, &filepaths, &count))
                        {
                            for (int i = 0; i < count; i++)
                            {
                                qDebug() << "selected file: " << filepaths[i];
                                m_filePaths.push_back(QString(filepaths[i]));
                            }
                            bps_free(filepaths);
                        }
                        emit selectionCompleted();
                    }
                    else
                    {
                        emit selectionCancelled();
                    }
    
                    qDebug() << "Got file browse dialog click";
                    shutdown = true;
                }
            }
        }
    
        if (m_dialog)
        {
            dialog_destroy(m_dialog);
        }
    }
    

    This class derives from QObject (by QThread) which means that it can be used by QML when it exposes properties and signals. The FileBrowseDialog class has 3 properties

    -multiple selection: a Boolean flag indicating if single or multiple selection is allowed

    -filepaths: a read only value that returns the list of files selected

    -Filters: a read/write value is where you can specify one or more filters to file (for example, ".doc", "*.jpg") etc.

    The next part is how you call the FileBrowseDialog through the QML. To do this, we must inform the QML of the FileBrowseDialog page. This is done in the App class via the qmlregistertype code.

    App.cpp

    #include 
    #include 
    #include 
    
    #include "app.hpp"
    #include "FileBrowseDialog.hpp"
    
    using namespace bb::cascades;
    
    App::App()
    {
        qmlRegisterType("Dialog.FileBrowse", 1, 0, "FileBrowseDialog");
        QmlDocument *qml = QmlDocument::create("main.qml");
        qml->setContextProperty("cs", this);
    
        AbstractPane *root = qml->createRootNode();
        Application::setScene(root);
    }
    

    The QML is now ready to be able to use the FileBrowseDialog. The example below is a page complete qml which has a button and a label. When we click on the FileBrowseDialog button is open, and all selected files will appear in the label.

    Main.QML

    import bb.cascades 1.0
    import Dialog.FileBrowse 1.0
    
    Page {
        content: Container {
            Label { id: filebrowseDialogLabel }
            Button {
                text : "File Browse Dialog"
                onClicked: {
                    filebrowseDialog.show();
                }
            }
            attachedObjects: [
                FileBrowseDialog {
                    id: filebrowseDialog
                    multiselect : true
                    filters : ["*.doc","*.jpg","*.txt"]
                    onSelectionCompleted: {
                        if(filebrowseDialog.filepaths.length>0)
                            filebrowseDialogLabel.text = filebrowseDialog.filepaths[0];
                        else
                            filebrowseDialogLabel.text = "no file selected";
                    }
                    onSelectionCancelled: {
                        filebrowseDialogLabel.text = "file browse dialog was cancelled";
                    }
                }
            ]
        }
    }
    

    And it's pretty much just invoke the native dialog file navigation in stunts. Please note save the file would follow a similar model, but I found that this dialog box was not particularly useful because it displays only a simple dialogbox with a text file name entry.

    See you soon

    Swann

  • Q_PROPERTY

    I'm confused about Q_PROPERTY

    can any body tell what "Q_PROPERTY (QString text text READ WRITE setText NOTIFY textChanged)" means

    Hello

    Q_PROPERTY is a macro and a part of the system of Qt properties. Its purpose is to allow us to bind the properties that we use in our QML to C++ data by appropriate methods. Your example combines three things a QML property whose id is "text". Let's review each of them:

    Text READ: it means "to get a value for the text property, call a C++ method text()".

    WRITE setText: in other words, "if we change the value of the text property to QML by assigning a value, communicate to C++ by calling a method, setText (QString NewText).

    TextChanged NOTIFY: This means that "If the value of the data in my C++ object is modified by a non - QML action, notify me that it has changed so that I can update the value of the property in QML by transmitting the signal of Qt, whose name is «textChanged()»»

    There is still information on the QML and C++ integration in our documentation here:

    http://developer.BlackBerry.com/native/documentation/Cascades/dev/integrating_cpp_qml/

    Here is an example of my own as well:

    Q_OBJECT
    
        // a Q_PROPERTY declaration is a binding between a property we can use in QML and underlying C++ methods and signals
    
    Q_PROPERTY(
            // the name of our property as used from QML
            QString my_property
            // a method that will be called to populate our QML property with a value from C++
            READ getMyProperty
            // a method that will be called when we want to change the value of our corresponding C++ variable
            WRITE setMyProperty
            // a signal that will be emitted if the underlying data value changes. This signal will be automatically connected to our QML property
            // so that anywhere our property has been used, it's value will be updated
            NOTIFY signalMyPropertyChanged)
    

    Figure 1 declaring a Q_PROPERTY

    And then we declare signals and the associated methods:

    public:
    
        // for my Q_PROPERTY
        QString getMyProperty();
        void setMyProperty(QString text);
    
        Q_INVOKABLE void resetMyProperty();
    
    signals:
        // signal that is emitted if my property value changes
        void signalMyPropertyChanged();
    

    Figure 2: declare the methods and signals used by the Q_PROPERTY

    private:
        QString _some_text;
    

    Figure 3: Our C++ data we bind to our property

    Note that I also used Q_INVOKABLE authorizing the call directly from the resetMyProperty() to the specified method of QML.

    QString ApplicationUI::getMyProperty() {
        qDebug() << "XXXX getMyProperty called";
        return _some_text;
    }
    
    void ApplicationUI::setMyProperty(QString some_text) {
        qDebug() << "XXXX setMyProperty called:" << some_text;
        _some_text = some_text;
        qDebug() << "XXXX setMyProperty emiting signalMyPropertyChanged";
        emit signalMyPropertyChanged();
    }
    
    void ApplicationUI::resetMyProperty() {
        qDebug() << "XXXX resetMyProperty called";
        setMyProperty("Hello I am a property");
    }
    

    Figure 4: implementation of C++ functions

        QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
    
        // expose the property to QML
        qml->setContextProperty("my_prop", this);
    

    Figure 5 expose our C++ object to QML

    import bb.cascades 1.2
    
    Page {
        Container {
    
            TextField {
                id: tf
                objectName: "tf"
                // this causes the READ method bound to our property to be called
                text: my_prop.my_property
            }
            Button {
                text: "Change Property"
                onClicked: {
                    // this causes the WRITE method bound to our property to be called
                    my_prop.my_property = tf.text
                }
            }
            Button {
                text: "Reset"
                onClicked: {
                    // this calls a C++ method that was exposed using Q_INVOKABLE
                    my_prop.resetMyProperty();
                }
            }
        }
    }
    

    Figure 6 the QML

    When I run my application, I see that TextField tf is generated automatically and this is accomplished by the system calling the getMyProperty READING method. So, if I change the text and click the button of change of ownership, I see that the WRITE method is called. If I click on Reset, the Q_INVOKABLE method is called directly from QML and it my signal, so notify the QML bound property value has changed. This causes a call to the READ method and my text field in QML is updated.

    XXXX getMyProperty called
    XXXX setMyProperty called: "Hello"
    XXXX setMyProperty emiting signalMyPropertyChanged
    XXXX getMyProperty called
    XXXX resetMyProperty called
    XXXX setMyProperty called: "Hello I am a property"
    XXXX setMyProperty emiting signalMyPropertyChanged
    XXXX getMyProperty called
    

    Figure 7: out of the call display console

    Hope that helps

    Martin

  • Cluster of buttons

    Hi guys,.

    I need help. In my example below, there are two tabs of page with a cluster of three buttons within each tab. In the block diagram, I have a while loop with a cluster of events with event Cluster 1 and Cluster 2 all the items selected. I also have a class of Cluster connected to a property with the exposed [] controls property node. I'm currently editing the Boolean text of the I pressed the button.

    Does anyone know how to do this? I can't expose properties that I need based on which button I clicked on. I hope I don't have to have an event for each button that is in each cluster. Which sucks.

    All the points in the right direction would be greatly appreciated.

    P.S. I use this instead of download my VI which has some SubVIs with her and each cluster has a different number of buttons associated with each cluster.

    Right then here's what you can do.  Get the reference of the cluster command that has been changed.  Then read the old value and a previous to see boolean value has changed.  Get references to the control in the cluster, and then remove the reference to the control that has changed its value.  Cast to a boolean class, then replace the text.  Now, if you want an error checking, because you can have Boolean values in your cluster.

Maybe you are looking for