QWidget到QML的过渡、区别、对应关系粗解(九)

Question: C++ (QWidgets) 中 读取文件什么的如何在QML中实现?

      Answer:   最简单熟悉的办法,使用C++/QFile来进行操作。即将C++引入到QtQuick中 (JavaScript的  Node.js框架也可以做,但是Node.js QML目前还不支持,需要额外设置,没必要考虑,除非特别熟悉后端的Node.js)

CPP版本的文件读写例子:

#ifndef FILEIO_HPP
#define FILEIO_HPP

#include <QObject>
//#include <QtQml/qqmlregistration.h>
#include <QFile>
#include <QTextStream>

class FileIO : public QObject
{
    Q_OBJECT
    //QML_ELEMENT
    Q_PROPERTY(QString content MEMBER m_strContent READ getContent WRITE setContent NOTIFY contentChanged);

public:
    explicit FileIO(){}

signals:
    void contentChanged();

public slots: /*slots已经实现了反射,所以不用挨个加上Q_INVOKABLE了*/
    bool writeIntoFile(const QString &path)
    {
        QFile file(path);
        if (file.open(QIODevice::WriteOnly | QIODevice::Text))
        {
            QTextStream out(&file);
            out << m_strContent;
            file.close();
            return true;
        }
        return false;
    }

    QString readFile(const QString &path)
    {
        m_strContent.clear();

        QFile file(path);
        if (file.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            QTextStream in(&file);
            m_strContent = in.readAll();
            file.close();
        }
        else
            m_strContent = "Error to read file";

        return m_strContent;
    }
public:
    //!QML中Component.attribute 中自动调用这两个函数,所有不用手动反射了
    QString getContent()const{return "getContent: " + m_strContent;}
    void setContent(const QString &str){m_strContent = "setContent: " +str;}
protected:
    QString m_strContent;

};
#endif // FILEIO_HPP
 

在main.cpp中进行注册

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "FileIO.hpp" // step1: import header file

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    //step 2: register a c++ class into QML
    qmlRegisterType<FileIO>("com.FileIO", 1, 0, "FileIO"); // 注册类型到QML中

    QQmlApplicationEngine engine;
    QObject::connect(
        &engine,
        &QQmlApplicationEngine::objectCreationFailed,
        &app,
        []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.loadFromModule("untitled", "Main");

    return app.exec();
}
 

调用实例:

Main.qml

import QtQuick
import QtQuick.Dialogs //注意和labs的略有不同,查帮助时弹出的对话框小心选一下
import QtQuick.Controls
import QtQuick.Layouts

//step3: import our FileIO C++ "Component"
import com.FileIO

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    function fileUrl2FileName(furl){
        let suffix = "file:///";
        //Notice: length is an attribute of Js string type, NOT a function
        var cppFileName = furl.toString().slice(suffix.length)
        console.log(cppFileName);
        return cppFileName;
    }

    //Component from CPP
    FileIO{
       id: cppFileIO
       content: "Hello, world !"
    }

    FileDialog{
        id: fd
        nameFilters: ["Text files(*.txt)","All files (*)"]
    }

    RowLayout{
        //相当于充满整个Window,即Designer中给Window(Widget)添加HBoxLayout
        anchors.fill: parent
        spacing: 0

        //fillHeight/fillWidth:true 即为Layout的自动充满模式
        Rectangle{ //write file
            Layout.fillHeight: true
            Layout.fillWidth: true
            color: Qt.lighter("green")

            //QtQuick.Controls
            TextField{
                id: te
                anchors.top : parent.top
                anchors.topMargin: 70
                anchors.horizontalCenter: parent.horizontalCenter
                width: 200
                placeholderText:  "file content here."
                background:Rectangle{
                    anchors.fill: parent
                    color: "white"
                }
            }

            //QtQuick.Controls
            Button{
                id: btnWrite
                anchors.top: te.bottom
                anchors.topMargin: 30
                anchors.horizontalCenter: te.horizontalCenter
                text: "clicked me to save input text"

                onClicked:{
                    fd.fileMode  =  FileDialog.SaveFile
                    fd.open();
                }
                Component.onCompleted: {
                    fd.accepted.connect(function (){
                        if(fd.fileMode == FileDialog.SaveFile){
                            cppFileIO.content = te.text
                            cppFileIO.writeIntoFile(fileUrl2FileName(fd.selectedFile));
                        }
                      }
                    );
                }
            }
        }
        Rectangle{ //read file
            Layout.fillHeight: true
            Layout.fillWidth: true
            color: Qt.lighter("steelblue")

            Text{
                id: fileContent
                anchors.centerIn: parent
                text: cppFileIO.content
                color: "green"
                wrapMode: Text.WordWrap
            }

            Button{
                id: btnRead
                anchors.horizontalCenter:   parent.horizontalCenter
                anchors.top: fileContent.bottom
                anchors.topMargin: 50
                text: "Click me to open a  text File"
                onClicked: {
                    fd.fileMode = FileDialog.OpenFile
                    fd.open();
                }
                Component.onCompleted: {
                    fd.accepted.connect(()=>{
                        if(fd.fileMode == FileDialog.OpenFile){
                            cppFileIO.readFile(fileUrl2FileName(fd.selectedFile));
                            fileContent.text = cppFileIO.content;
                        }
                    })
                }
            }

            Text{
                id: fileName
                anchors.top: btnRead.bottom
                anchors.topMargin: 50
                anchors.horizontalCenter: parent.horizontalCenter
                text: fd.currentFile
                color: "red"
            }

        }
    }

}
 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值