c++qtqmlqt-creatorqqmllistproperty

Exposing to QML the serial port names from C++


I'm trying to expose the QSerialPort.available() through an Q_INVOKABLE QStringList availablePorts() function from a class I expose directly to QML in my main class.

Main:

qmlRegisterType<SerialPortManager>("com.MyApp.qml", 1, 0, "SerialPortManager");

SerialPortManager

class SerialPortManager : public QObject
{
    Q_OBJECT
public slots:
    Q_INVOKABLE virtual QStringList availablePorts() {
        QList<QSerialPortInfo> portsAvailable = QSerialPortInfo::availablePorts();
        QStringList names_PortsAvailable;
        for(QSerialPortInfo portInfo : portsAvailable) {
            names_PortsAvailable.append(portInfo.portName());
        }

        return names_PortsAvailable;
    }

Which is not valid for a model type in QML because it raises Unable to assign QStringList to QQmlListModel* error.

QML

ComboBox {
    model: serial.availablePorts()
}
SerialPortManager {
    id: serial
}

So how do I get around this?


Solution

  • One solution is to return a QVariant as recommended by the docs, for this we use QVariant::fromValue()

    #ifndef SERIALPORTMANAGER_H
    #define SERIALPORTMANAGER_H
    
    #include <QObject>
    #include <QSerialPortInfo>
    #include <QVariant>
    
    class SerialPortManager : public QObject
    {
        Q_OBJECT
    public:
        Q_INVOKABLE static QVariant availablePorts() {
            QList<QSerialPortInfo> portsAvailable = QSerialPortInfo::availablePorts();
            QStringList names_PortsAvailable;
            for(const QSerialPortInfo& portInfo : portsAvailable) {
                names_PortsAvailable<<portInfo.portName();
            }
            return QVariant::fromValue(names_PortsAvailable);
        }
    };
    
    #endif // SERIALPORTMANAGER_H