QML: TypeError: Property 'contains' of object ... is not a function

Начинаю в Qt Quick и столкнулся с проблемой. Есть класс

class CanHandler : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QStringList plugins READ plugins NOTIFY pluginsChanged)
    Q_PROPERTY(QStringList interfaceNames READ interfaceNames NOTIFY interfacesChanged)
    Q_PROPERTY(QString selectedPlugin READ selectedPlugin WRITE setSelectedPlugin NOTIFY selectedPluginChanged)
public:
    explicit CanHandler(QObject *parent = nullptr);

    QStringList plugins() const { return m_plugins; }
    QStringList interfaceNames() const { return m_interfaceNames; }
    QString selectedPlugin() const { return m_selectedPlugin; }

signals:
    void pluginsChanged();
    void interfacesChanged();
    void selectedPluginChanged();

public slots:
    void setSelectedPlugin(const QString &pluginName)
    {
        if (pluginName == m_selectedPlugin)
            return;

        m_selectedPlugin = pluginName;
        updateInterfaceNames();
        emit selectedPluginChanged();
    }

private:
    QStringList m_plugins;
    QList<QCanBusDeviceInfo> m_interfaces;
    QStringList m_interfaceNames; // Store names for QML access
    QString m_selectedPlugin;

    void updateInterfaceNames() {
        m_interfaceNames.clear();
        if (!m_selectedPlugin.isEmpty()) {
            m_interfaces = QCanBus::instance()->availableDevices(m_selectedPlugin);
            for (const auto &info : m_interfaces) {
                m_interfaceNames.append(info.name());
            }
        }

        emit interfacesChanged();
    }
};

Есть CanPluginComboBox.qml

ComboBox {
    id: pluginComboBox
    property var can: null
    model: can ? can.plugins : []
    Component.onCompleted: {
        // Initialize currentIndex based on selectedPlugin
        if (can && can.plugins.contains(can.selectedPlugin)) {
            currentIndex = can.plugins.indexOf(can.selectedPlugin);
        } else if (can && can.plugins.length > 0) {
            currentIndex = 0;
        }
    }
    onActivated: can.setSelectedPlugin(currentText)

    Connections {
        target: can
        ignoreUnknownSignals: true

        onSelectedPluginChanged: {
            if (can && can.plugins.contains(can.selectedPlugin)) {
                currentIndex = can.plugins.indexOf(can.selectedPlugin);
            }
        }
    }
}

Есть SettingsPageForm.ui.qml

Page {
    width: 1024
    height: 700

    title: qsTr("Settings")

    Label {
        text: qsTr("You are on Page 2.")
        anchors.centerIn: parent
    }

    CanPluginComboBox {
        // Use the custom component
        id: plugin_ComboBox
        can: can0
        width: 170
    }

    ComboBox {
        id: comboBox_canInterface
        x: 317
        y: 65
        width: 128
        model: can0.interfaceNames
    }
}

и в main.qml:

CanHandler {
   id: can0
}

Проблема в строчке can.plugins.contains(can.selectedPlugin)) получаю ошибку:

TypeError: Property 'contains' of object passthrucan,peakcan,socketcan,tinycan,virtualcan is not a function

console.log("can.plugins =", can.plugins)

выводит массив qml: can.plugins = [passthrucan,peakcan,socketcan,tinycan,virtualcan] но проверку на массив не проходит

if (Array.isArray(can.plugins)) {
    console.log("can.plugins is array")
} else {
    console.error("can.plugins is not array!")
}

Ответы (1 шт):

Автор решения: Andrey Sokolov

Если на пальцах, то когда вы передаете plugins как property, то в qml он уже не QStringList, а обычный javascript-массив. То есть работать с ним нужно методами javascript-а. Не знаю насчет проверки на массив, но, судя по выводу console.log, массив вполне нормальный. Попробуйте вместо contains(), что-нибудь вроде indexOf()

→ Ссылка