[英]qml Unknown method return type: ArchiveFile*, even though qmlRegisterUncreatableType was called
I'm trying to make an application for opening some very structurally similar, related files. 我正在尝试创建一个应用程序来打开一些结构相似的相关文件。 Í have a base class, named GenericFile
, and a subclass, named ArchiveFile
. Í有一个名为GenericFile
的基类和一个名为ArchiveFile
的子类。 There also exists subclasses of ArchiveFile
, which contain implementation logic for the specific archive file format, but those are not relevant for QML and therefore not exposed to QML. 还存在ArchiveFile
子类,它包含特定存档文件格式的实现逻辑,但这些子类与QML无关,因此不会暴露给QML。
I've yet another class named FileManager
, which exposes certain methods to QML to create instances of GenericFile
and to downcast them to classes like ArchiveFile
, based on GenericFile.getFileCategory
. 我还有另一个名为FileManager
类,它将某些方法暴露给QML以创建GenericFile
实例,并将它们ArchiveFile
到ArchiveFile
等基于GenericFile.getFileCategory
。
I've registered both GenericFile
and ArchiveFile
using qmlRegisterUncreatableType
, like this: 我已经注册都GenericFile
和ArchiveFile
使用qmlRegisterUncreatableType
,就像这样:
int main(int argc, char** argv) {
QApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterUncreatableType<GenericFile>("me.henkkalkwater", 1, 0, "GenericFile", "Get your copy of GenericFile using FileManager!");
qmlRegisterUncreatableType<ArchiveFile>("me.henkkalkwater", 1, 0, "ArchiveFile", "Get your copy of ArchiveFile using FileManager!");
qmlRegisterSingletonType<FileManager>("me.henkkalkwater", 1, 0, "FileManager", [](QQmlEngine* engine, QJSEngine* jsEngine) -> QObject* {
Q_UNUSED(engine)
Q_UNUSED(jsEngine)
return new FileManager();
});
const QUrl url(QStringLiteral("qrc:/qml/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
}
Calling GenericFile* FileManager.getFile(int index)
works fine in QML. 调用GenericFile* FileManager.getFile(int index)
在QML中工作正常。 But calling ArchiveFile* FileManager.getArchive(int index)
doesn't work, with the message "Error: Unknown method return type: ArchiveFile*". 但是调用ArchiveFile* FileManager.getArchive(int index)
不起作用,消息“Error:Unknown method return type:ArchiveFile *”。
Has the problem to do with the fact that ArchiveFile
inherits from GenericFile
or did I make a silly mistake somewhere else? 已经做的事实问题ArchiveFile
从继承GenericFile
还是我做出愚蠢的错误别的地方? Or is the design of my classes seriously flawed? 或者我的课程设计严重缺陷? Am I taking some Java conventions to C++ which should be done in another way? 我是否将一些Java约定用于C ++,这应该以另一种方式完成?
genericfile.h: genericfile.h:
class GenericFile;
typedef GenericFile* (*CreateFileFunction) (QIODevice* file, QString fileName, QObject* parent);
class GenericFile : public QObject {
Q_OBJECT
public:
enum FileCategory {
UNKNOWN,
COMPRESSED,
ARCHIVE,
LAYOUT
};
Q_ENUM(FileCategory)
GenericFile(QIODevice* source, QString name, QObject* parent = nullptr);
virtual ~NinFile();
Q_PROPERTY(QString fileName READ getFileName)
Q_PROPERTY(FileCategory fileCategory READ getFileCategory)
/**
* @brief Register a file usign a certain string of magic bytes.
* @param magic
* @param fn
*/
static void RegisterFile(QLatin1String magic, CreateFileFunction fn);
/**
* @brief Return one of the subclasses of the file.
* @param file The file to determine.
* @return The class able to parse this file format.
*
* Scans the magic bytes and returns a subclass of GenericFile that represents the file.
* The subclass will take ownership of the QFile and destroy it whenever it is destroyed
* itself.
*/
static GenericFile* fromFile(QFile* file, QObject* parent = nullptr);
static GenericFile* fromIODevice(QIODevice* file, QString filename, QObject* parent = nullptr);
/**
* @brief Initialize the default file associations.
*/
static void init();
/**
* @return The filename of this file
*/
QString getFileName() const {
return fileName;
}
/**
* @return return the general category the file belongs in
*/
virtual FileCategory getFileCategory() const {
return UNKNOWN;
}
protected:
QIODevice* file;
QString fileName;
};
archivefile.h archivefile.h
class ArchiveFile : public GenericFile
{
public:
ArchiveFile(QIODevice* device, QString fileName, QObject* parent = nullptr);
Q_INVOKABLE
virtual QList<QString> listContents() = 0;
FileCategory getFileCategory() const override { return GenericFile::ARCHIVE; }
};
FileManager.h (with relevant method implementations included) FileManager.h(包含相关的方法实现)
class FileManager : public QAbstractListModel
{
Q_OBJECT
public:
explicit FileManager(QObject *parent = nullptr);
enum RoleNames {
INDEX = Qt::UserRole + 1,
PATH,
TYPE,
CATEGORY
};
/**
* @brief Opens a file
* @param filePath The path to the file
* @return false if the opening fails, true otherwise
* Opens a file, and if successful, returns true and adds it to this model. Otherwise, it returns false.
*/
Q_INVOKABLE
bool openFile(QUrl filePath);
Q_INVOKABLE
GenericFile* getFile(int index) {
if (index >= 0 && index < files.length()) {
return files[index];
}
return nullptr;
}
Q_INVOKABLE
ArchiveFile* getArchive(int index) {
qDebug() << "Callled getArchive";
try {
return dynamic_cast<ArchiveFile*>(getFile(index));
} catch (std::bad_cast e){
return nullptr;
}
}
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
private:
QList<GenericFile*> files;
};
Edit: it appears that this happens every time I register a base class and a subclass of said baseclass. 编辑:似乎每次我注册基类和所述基类的子类时都会发生这种情况。
Adding the Q_OBJECT
macro to the subclass ( ArchiveFile
) seems to resolve the issue. 将Q_OBJECT
宏添加到子类( ArchiveFile
)似乎可以解决此问题。 I wrongly assumed that you only had to define the Q_OBJECT
macro in the base class ( GenericFile
) somehow. 我错误地认为你只需要以某种方式在基类( GenericFile
)中定义Q_OBJECT
宏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.