設定した特定のプロパティを持つコンポーネントを作成しようとしています。サウンドの場所と名前は、console.log()に次のように表示されるため、実際に動作しているC++関数によって指定されます。
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
問題は、プロパティをListElementに設定しようとすると、プロパティが認識されなかったかのように、ListViewを空のままにしてしまうことです。
ファイル内のJavasCript関数は次のとおりです。
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());
}
使用されるページは次のとおりです。
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"
}
}
リストセレクターに使用されるコンポーネントは次のとおりです。これは、JS関数を操作する必要があるコンポーネントです。
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")
}
}
}
そして、JSファイルで使用されるNameプロパティとSoundプロパティを定義するListElementは次のとおりです。
ListElement {
id: soundsListElement
objectName: "soundsListElement"
property string Name
property string Sound
name: Name
sound: Sound
}
私の問題は、JSはNameとSoundがListElementの文字列プロパティであることを理解していないようであり、ListViewコンポーネントに存在する関数で指定されたsoundNameとsoundLocationでそれらを設定する必要があるためですページ。代わりに、アイテムセレクターは完全に空になります。
私が間違っていることを見つけることができません。どんな助けでも大歓迎です。
here の例に従ったと思いますが、あなたの場合はconnect
をcomponent.statusChanged
信号にしようとしていますが、同時にfinishCreation
ハンドラーは引数を受け入れます。不可能です。
シグナルに接続されると、送信されると、finishCreation
を引数なしで呼び出します。空のアイテムが表示される理由はこれで説明できると思います。
シグナルハンドラーが呼び出されたときに、soundName
とsoundLocation
の両方にアクセスできるようにするには、jsファイルのcomponent
とelement
のようにグローバルにします(未テスト) :
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());
}
それを修正しました。 ListElementコンポーネントを作成すべきではないようです。代わりに、ListModelは次のようになります。
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])
}
}
JavaScriptファイルは次のようになります。
function makeList(id, soundName, soundLocation) {
id.append({"name" : soundName, "sound" : soundLocation})
}
リストに追加する必要があります。