3

I am trying to create a component with certain properties I've set. The sounds location and name are given by a C++ function that is actually working because the console.log() shows so:

qml: Adding /home/vitimiti/.local/share/com.ubuntu.developer.vitimiti.irc-app/sounds/Amsterdam.ogg sound
qml: Adding /home/vitimiti/.local/share/com.ubuntu.developer.vitimiti.irc-app/sounds/Blip.ogg sound
qml: Adding /home/vitimiti/.local/share/com.ubuntu.developer.vitimiti.irc-app/sounds/Mallet.ogg sound
qml: Adding /home/vitimiti/.local/share/com.ubuntu.developer.vitimiti.irc-app/sounds/Positive.ogg sound
qml: Adding /home/vitimiti/.local/share/com.ubuntu.developer.vitimiti.irc-app/sounds/Rhodes.ogg sound
qml: Adding /home/vitimiti/.local/share/com.ubuntu.developer.vitimiti.irc-app/sounds/Slick.ogg sound
qml: Adding /home/vitimiti/.local/share/com.ubuntu.developer.vitimiti.irc-app/sounds/Soft delay.ogg sound
qml: Adding /home/vitimiti/.local/share/com.ubuntu.developer.vitimiti.irc-app/sounds/Xylo.ogg sound

The problem is that, when trying to set the properties to a ListElement, it will simply leave the ListView empty, as if it didn't recognize the properties.

Here is my JavasCript Functions in a file:

var component;
var element;

function createElement(soundName, soundLocation) {
    component = Qt.createComponent("../AlertsSettingsSounds.qml")
    if (component.status === Component.Ready)
        finishCreation(soundName, soundLocation)
    else
        component.statusChanged.connect(finishCreation)
}

function finishCreation(soundName, soundLocation) {
    if (component.status === Component.Ready) {
        element = component.createObject(alertsModel, {
                                             "Name": soundName,
                                             "Sound": soundLocation});

        if (element === null)
            // Error Handling
            console.log("Error creating object");
    } else if (component.status === Component.Error)
        // Error Handling
        console.log("Error loading component: ", component.errorString());
}

Here is the page that is used:

import QtQuick 2.0
import Ubuntu.Components 1.1
import Ubuntu.Components.ListItems 1.0 as ListItem

import Irc_App 0.1

import "../components"

// Mobile (small screen) layout
Page {
    id: alertsSettingsPage
    objectName: "alertSettingsPage"

    title: i18n.tr("Alerts")

    Row {
        id: muteRow
        objectName: "muteRow"

        anchors {
            left: parent.left
            leftMargin: root.margins
            top: parent.top
            topMargin: root.margins
            right: parent.right
            rightMargin: root.margins
        }

        spacing: root.spacing

        Label {
            id: muteLabel
            objectName: "muteLabel"

            width: parent.width - muteCheckBox.width

            text: i18n.tr("<b>Mute</b> notifications")
        }

        CheckBox {
            id: muteCheckBox
            objectName: "muteCheckBox"

            checked: false
            onCheckedChanged: {
                if (checked === true)
                    soundsComponent.volume = 0
                else
                    soundsComponent.volume = 1
            }
        }
    }

    Flickable {
        id: soundsFlickable
        objectName: "soundsFlickable"

        anchors {
            left: parent.left
            leftMargin: root.margins
            top: muteRow.bottom
            right: parent.right
            rightMargin: root.margins
            bottom: parent.bottom
            bottomMargin: root.margins
        }

        clip: true
        contentHeight: soundsColumn.height
        contentWidth: parent.width
        flickableDirection: Flickable.VerticalFlick

        Column {
            id: soundsColumn
            objectName: "soundsColumn"

            width: parent.width
            spacing: root.spacing

            // One item selector for each notification there is.
            ListItem.ItemSelector {
                id: highlightAlertSelector
                objectName: "highlightAlertSelector"

                text: i18n.tr("Highlight Alert")
                expanded: false
                model: alertsSettingsComponent

                onSelectedChanged: {
                    console.log(selectedIndex + " selected")
                }

                delegate: OptionSelectorDelegate {
                    text: name
                    onClicked: {
                        // This functions are local and to make the alerts
                        // sound as they ought to. They will write the
                        // configuration to the xml file and, from there,
                        // the program will start with those options set
                        // and the events will read such file to set again the
                        // Audio component and make it work for just the event.
                        if (name === "Muted") {
                            console.log("Muting sound for highlights")
                            soundsComponent.source = ""
                        } else {
                            console.log("Starting sound " + name +
                                        " for highlights")
                            console.log("Setting sound option " + name +
                                        " for highlights")
                            soundsComponent.source =
                                    soundsHandler.soundsLocation + "/" + name
                            soundsComponent.play()
                        }
                    }
                }

                Component.onCompleted: {
                    // Set the muteCheckBox as it is in the configuration
                    // Set the sounds as they are in the configuration file
                }
            }

            ListItem.ItemSelector {
                id: kickedAlertsSelector
                objectName: "kickedAlertsSelector"

                text: i18n.tr("Kicked Alert")
                expanded: false
                model: alertsSettingsComponent

                onSelectedChanged: {
                    console.log(selectedIndex + " selected")
                }

                delegate: OptionSelectorDelegate {
                    text: name
                    onClicked: {
                        if (name === "Muted") {
                            console.log("Muting sound for kicked event")
                            soundsComponent.source = ""
                        } else {
                            console.log("Starting sound " + name +
                                        " for kicked event")
                            console.log("Setting sound option " + name +
                                        " for kicked event")
                            soundsComponent.source =
                                    soundsHandler.soundsLocation + "/" + name
                            soundsComponent.play()
                        }
                    }
                }

                Component.onCompleted: {
                    // Set the muteCheckBox as it is in the configuration
                    // Set the sounds as they are in the configuration file
                }
            }
        }
    }

    AlertsSettingsComponent {
        id: alertsSettingsComponent
        objectName: "alertsSettings_component"
    }

    SoundsComponent {
        id: soundsComponent
        objectName: "sounds_component"
    }
}

Here is the component used for the List Selectors, which is the one that should be working with the JS functions:

import QtQuick 2.0

import Irc_App 0.1

import "../js/AlertsSettingsFunctions.js" as AlertsSettingsFunction

// Using the sounds from the folder
ListModel{
    id: alertsModel
    objectName: "alertsModel"

    Component.onCompleted: {
        for (var i = 0; i < soundsHandler.sounds.length; i++) {
            AlertsSettingsFunction.createElement(soundsHandler.sounds[i],
                        soundsHandler.soundsLocation + "/"
                        + soundsHandler.sounds[i])
            console.log("Adding", soundsHandler.soundsLocation + "/"
                        + soundsHandler.sounds[i], "sound")
        }
    }
}

And here is the ListElement that defines the Name and Sound properties used in the JS file:

ListElement {
    id: soundsListElement
    objectName: "soundsListElement"

    property string Name
    property string Sound

    name: Name
    sound: Sound
}

So my problem is that the JS doesn't seem to understand that Name and Sound are string properties for the ListElement and that it should set them with the given soundName and soundLocation in the function present in the ListView component, so as to show it in the page. Instead, the Item Selectors appear completely empty.

I can't find out what I'm doing wrong, any help would be much appreciated.

2 Answers 2

2

I think you followed the example given here, but in your case you're trying to connect to the component.statusChanged signal and at the same time expecting to see the finishCreation handler to accept arguments. It's not possible.

Once connected to the signal, if emitted it will call finishCreation without arguments. I guess that explains why you're seeing empty items.

To ensure that when the signal handler is called you have access to both soundName and soundLocation I would make them globals, like component and element in the js file (untested):

var component;
var element;
var _soundName;
var _soundLocation;

function createElement(soundName, soundLocation) {
    component = Qt.createComponent("../AlertsSettingsSounds.qml")
    _soundName = soundName
    _soundLocation = soundLocation
    if (component.status === Component.Ready)
        finishCreation()
    else
        component.statusChanged.connect(finishCreation)
}

function finishCreation() {
    if (component.status === Component.Ready) {
        element = component.createObject(alertsModel, {
                                             "Name": _soundName,
                                             "Sound": _soundLocation});

        if (element === null)
            // Error Handling
            console.log("Error creating object");
    } else if (component.status === Component.Error)
        // Error Handling
        console.log("Error loading component: ", component.errorString());
}
4
  • I have tested it and added console.log(_soundName) and console.log(_soundLocation). Both variables are correct and do work as expected. Still, the List Selectors are empty. I double checked the path to the qml file and it is correct. Sep 30, 2014 at 12:10
  • @VíctorMatíaRodríguez Could it be possible to link to your question where we could find your code online (launchpad/github). Even if your questions already provides the main files, It's hard to figure out how your project is organized (e.g import ../components). Thanks Sep 30, 2014 at 12:17
  • @SylvianPineau It is here: bazaar.launchpad.net/~vitimiti/irc-app/trunk/files Sep 30, 2014 at 12:20
  • Update: while console.log(component) does show a component, console.log(element) does not show so. Neither does console.log(_soundName) or console.log("TEST"). This means the function that is NOT working is actually finishCreation(). Sep 30, 2014 at 17:00
0

Fixed it. It appears to be that I should not create a ListElement component. Instead, the ListModel should look like:

import QtQuick 2.0

import Irc_App 0.1

import "../js/AlertsSettingsFunctions.js" as AlertsSettingsFunction

// Using the sounds from the folder
ListModel {
    id: alertsModel
    objectName: "alertsModel"

    Component.onCompleted: {
        for (var i = 0; i < soundsHandler.sounds.length; i++)
            AlertsSettingsFunction.makeList(alertsModel,
                                            soundsHandler.sounds[i],
                                            soundsHandler.soundsLocation + "/"
                                            + soundsHandler.sounds[i])
    }
}

And the JavaScript file should look like:

function makeList(id, soundName, soundLocation) {
    id.append({"name" : soundName, "sound" : soundLocation})
}

It should be appended to the list.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .