简体   繁体   中英

Change a c++ class attribute from a QML text input

Alright, so the title says exactly what I'm trying to do. I'll show you the code and the issue I have.

What I want to do


I'm trying to open a file from a click on a button with a custom file name entered in a textInput . This textInput is handled through my AntennaFile class. The file opening happens in the openButtonClicked function.

The issue I have


My m_fileName attribute doesn't have a value in the openButtonClicked function even though it has one in the setFileName one (I checked in debug with breakpoints and with qDebug() ).

So how does one make the attribute not "lose" it's value? I'm surely missing something very simple and important for all of this to work and it's driving me crazy.

So here is all the needed code (I think?) so you can see exactly what I have done.

antennafile.cpp

#include "antennafile.h"

AntennaFile::AntennaFile(QObject *parent) : QObject(parent)
{
}

QString AntennaFile::getFileName()
{
    return m_fileName;
}

void AntennaFile::setFileName(const QString &fileName)
{
    if (fileName != m_fileName)
    {
        m_fileName = fileName;
        emit fileNameChanged();
        qDebug() << m_fileName; // Here, m_fileName has the value of what I typed in the textInput
    }
}

void AntennaFile::processFile(QString fileName, QVector<QString> &vecOfStrs)
{
    // Code removed for smaller post
}

void AntennaFile::openButtonClicked()
{
    QVector<QString> vecOfStrs;
    QString nameOfFile = "../QMLStageProject/AntennaTypes/";
    nameOfFile.append(m_fileName);
    qDebug() << nameOfFile; // Here, m_fileName is empty, hence, nothing is changed to nameOfFile

    processFile(nameOfFile, vecOfStrs);
}

antennafile.h

#ifndef AntennaFile_H
#define AntennaFile_H

#include "framework.h"
#include "antennadata.h"

class AntennaFile : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString fileName READ getFileName WRITE setFileName NOTIFY fileNameChanged)

public:
    explicit AntennaFile(QObject *parent = 0);
    QString getFileName();
    void setFileName(const QString &fileName);

private:
    void processFile(QString fileName, QVector<QString> & vecOfStrs);

public slots:
    void  openButtonClicked();

signals:
    void fileNameChanged();

private:
    QString m_fileName;
};

#endif // AntennaFile_H

main.cpp

#include "framework.h"
#include "antennafile.h"
#include "antennatablemodel.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;

    const QUrl url(QStringLiteral("qrc:/main.qml"));

    AntennaFile antennaFile;
    engine.rootContext()->setContextProperty("_AntennaFile", &antennaFile);

    // Registers
    qmlRegisterType<AntennaFile>("AntennaFile", 1, 0, "AntennaFile");
    qmlRegisterType<AntennaTableModel>("AntennaTableModel", 1, 0, "AntennaTableModel"); // An other class

    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);

    engine.load(url);

    return app.exec();
}

main.qml - not all the code again, just what is needed

import QtQuick 2.12
import QtQuick 2.6
import QtQuick.Window 2.12
import QtQuick.Controls 1.4
import QtQuick.Controls 2.0
import QtQuick.Controls 2.14
import QtCharts 2.3

import AntennaFile 1.0;
import AntennaTableModel 1.0;

Window
{
    id: window
    visible: true
    width: 950
    height: 680
    title: qsTr("QML Stage Project")

    AntennaFile {
        id: antennafile
    }

    TextInput {
        id: antennaTextInput
        x: 92
        y: 14
        width: 351
        height: 20
        text: antennafile.fileName
        font.pixelSize: 17
        onTextChanged: antennafile.fileName = text
    }

    Button {
        id: openButton
        x: 363
        y: 0
        width: 170
        height: 31
        text: qsTr("Open")
        font.pixelSize: 15
        onClicked: _AntennaFile.openButtonClicked();
    }
}

you have two instances of AntennaFile. The first one as context property. The second one in your main.qml, Your are not using the same one for the text edit and button: Changing your code like this, should work:

import QtQuick 2.12
import QtQuick 2.6
import QtQuick.Window 2.12
import QtQuick.Controls 1.4
import QtQuick.Controls 2.0
import QtQuick.Controls 2.14
import QtCharts 2.3

import AntennaFile 1.0;
import AntennaTableModel 1.0;

Window
{
    id: window
    visible: true
    width: 950
    height: 680
    title: qsTr("QML Stage Project")

    AntennaFile {
        id: antennafile
    }

    TextInput {
        id: antennaTextInput
        x: 92
        y: 14
        width: 351
        height: 20
        text: antennafile.fileName
        font.pixelSize: 17
        onTextChanged: antennafile.fileName = text
    }

    Button {
        id: openButton
        x: 363
        y: 0
        width: 170
        height: 31
        text: qsTr("Open")
        font.pixelSize: 15
        onClicked: antennafile.openButtonClicked();
    }
}

You can actually delete these lines from your main:

AntennaFile antennaFile;
engine.rootContext()->setContextProperty("_AntennaFile", &antennaFile);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM