我正在尝试创建一个具有我已设置的特定属性的组件。声音位置和名称由 C++ 函数提供,该函数实际上正在运行,因为 console.log() 显示如下:
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 设置它们,以便在页面中显示它。相反,项目选择器看起来完全是空的。
我不知道我做错了什么,如能得到任何帮助我将非常感激。
答案1
我认为你遵循了给出的例子这里,但就你的情况而言,你试图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());
}
答案2
已修复。看来我不应该创建 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})
}
应当将其附加到列表中。