【问题标题】:QML Check if file/image exists before getting the errorQML 在收到错误之前检查文件/图像是否存在
【发布时间】:2018-07-17 16:17:34
【问题描述】:

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

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

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

谢谢!

【问题讨论】:

    标签: image qt qml


    【解决方案1】:

    目前无法单独使用 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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-13
      • 1970-01-01
      • 2019-03-07
      • 1970-01-01
      • 2018-02-20
      • 2012-02-10
      • 2015-07-11
      • 1970-01-01
      相关资源
      最近更新 更多