QML在收到错误之前检查文件/图像是否存在

时间:2018-02-07 11:29:59

标签: image qt qml

我想检查本地目录中是否存在图像,如果不存在,则加载默认图像。我使用以下方法找到了锻炼:

    Image {
        id: image
        source: source1
        onStatusChanged: {
            if ( (image.status == Image.Error) && source !== default_source ) {
                source = default_source
            }
        }
    }

但我更愿意在收到错误之前测试文件是否存在。在尝试加载之前,有没有更简洁的方法来测试file_paths / url / images?

谢谢!

1 个答案:

答案 0 :(得分:3)

单凭QML目前无法做到这一点。

我写了一个C ++类来完成我的一个项目:

https://github.com/mitchcurtis/slate/blob/master/lib/filevalidator.h

/*
    Copyright 2016, Mitch Curtis

    This file is part of Slate.

    Slate is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Slate is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Slate. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef FILEVALIDATOR_H
#define FILEVALIDATOR_H

#include <QObject>
#include <QUrl>

class FileValidator : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
    Q_PROPERTY(bool fileValid READ isFileValid NOTIFY fileValidChanged)
    Q_PROPERTY(QString fileErrorMessage READ fileErrorMessage WRITE setFileErrorMessage NOTIFY fileErrorMessageChanged)
    Q_PROPERTY(bool treatAsImage READ treatAsImage WRITE setTreatAsImage NOTIFY treatAsImageChanged)

public:
    explicit FileValidator(QObject *parent = 0);

    QUrl url() const;
    void setUrl(const QUrl &url);

    bool isFileValid() const;

    QString fileErrorMessage() const;
    void setFileErrorMessage(const QString &fileErrorMessage);

    bool treatAsImage() const;
    void setTreatAsImage(bool treatAsImage);

signals:
    void urlChanged();
    void fileValidChanged();
    void fileErrorMessageChanged();
    void treatAsImageChanged();

protected:
    virtual void validate();

    QUrl mUrl;
    QString mFileErrorMessage;
    bool mTreatAsImage;
};

#endif // FILEVALIDATOR_H

https://github.com/mitchcurtis/slate/blob/master/lib/filevalidator.cpp

/*
    Copyright 2016, Mitch Curtis

    This file is part of Slate.

    Slate is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Slate is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Slate. If not, see <http://www.gnu.org/licenses/>.
*/

#include "filevalidator.h"

#include <QFile>
#include <QImage>

FileValidator::FileValidator(QObject *parent) :
    QObject(parent),
    mTreatAsImage(false)
{
    setFileErrorMessage("Must specify a file");
}

QUrl FileValidator::url() const
{
    return mUrl;
}

void FileValidator::setUrl(const QUrl &url)
{
    if (url == mUrl)
        return;

    mUrl = url;

    if (mUrl.isEmpty()) {
        setFileErrorMessage(tr("Must specify a file"));
    } else if (!QFile::exists(mUrl.toLocalFile())) {
        setFileErrorMessage(tr("File doesn't exist"));
    } else {
        if (mTreatAsImage) {
            QImage image(mUrl.toLocalFile());
            if (image.isNull()) {
                setFileErrorMessage(tr("Image can not be opened"));
            } else {
                // The image was loaded successfully, so we can clear
                // whatever was here before.
                setFileErrorMessage(QString());
            }
        } else {
            // The file was loaded successfully.
            setFileErrorMessage(QString());
        }
    }

    if (mFileErrorMessage.isEmpty()) {
        // Let derived classes check for problems.
        validate();
    }
    emit urlChanged();
}

bool FileValidator::isFileValid() const
{
    return mFileErrorMessage.isEmpty();
}

QString FileValidator::fileErrorMessage() const
{
    return mFileErrorMessage;
}

void FileValidator::setFileErrorMessage(const QString &fileErrorMessage)
{
    if (fileErrorMessage == mFileErrorMessage)
        return;

    bool wasValid = isFileValid();

    mFileErrorMessage = fileErrorMessage;
    if (isFileValid() != wasValid) {
        emit fileValidChanged();
    }

    emit fileErrorMessageChanged();
}

bool FileValidator::treatAsImage() const
{
    return mTreatAsImage;
}

void FileValidator::setTreatAsImage(bool treatAsImage)
{
    if (treatAsImage == mTreatAsImage)
        return;

    mTreatAsImage = treatAsImage;
    emit treatAsImageChanged();
}

void FileValidator::validate()
{
}

然后您将其注册到QML:

qmlRegisterType<FileValidator>("App", 1, 0, "FileValidator");

并像这样使用它:

import QtQuick 2.9
import QtQuick.Controls 2.0
import App 1.0

ApplicationWindow {
    width: 400
    height: 400
    visible: true

    FileValidator {
        id: validator
        url: source1
        treatAsImage: true
    }

    Image {
        source: validator.fileValid ? source1 : default_source
    }
}