qml 未知方法返回类型:ArchiveFile*,即使调用了 qmlRegisterUncreatableType
qml Unknown method return type: ArchiveFile*, even though qmlRegisterUncreatableType was called
简要描述我正在尝试做的事情
我正在尝试制作一个应用程序来打开一些结构非常相似的相关文件。Í 有一个名为GenericFile
的基类和一个名为ArchiveFile
的子类。还存在ArchiveFile
的子类,它们包含特定归档文件格式的实现逻辑,但这些子类与 QML 无关,因此不会向 QML 公开。
我还有另一个名为FileManager
的类,它向 QML 公开了某些方法以创建GenericFile
实例并将它们向下转换为基于GenericFile.getFileCategory
的
ArchiveFile
。问题所在
我已经使用qmlRegisterUncreatableType
注册了GenericFile
和ArchiveFile
,如下所示:
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);
}
调用GenericFile* FileManager.getFile(int index)
在 QML 中工作正常。但是调用ArchiveFile* FileManager.getArchive(int index)
不起作用,并显示消息"错误:未知方法返回类型:存档文件*"。
问题是否与ArchiveFile
继承自GenericFile
的事实有关,还是我在其他地方犯了一个愚蠢的错误?还是我的课程设计存在严重缺陷?我是否采用一些 Java 约定来C++应该以另一种方式完成?
我的代码
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;
};
存档文件.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(包括相关的方法实现)
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;
};
编辑:似乎每次我注册基类和所述基类的子类时都会发生这种情况。
将Q_OBJECT
宏添加到子类 (ArchiveFile
) 似乎可以解决问题。我错误地认为你只需要以某种方式在基类(GenericFile
)中定义Q_OBJECT
宏。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- C++为什么尽管我调用了void函数,它却不起作用
- 构造函数正在调用一个使用当前类类型的函数
- 变量没有改变?通过向量的函数调用
- 没有为自己的结构调用列表推回方法
- 调用'begin(int [n])'没有匹配函数
- 什么时候调用析构函数
- 如何用参数值调用函数(仅在运行时已知)
- std::cout.imbue()多重调用
- 函数何时会在c++中包含stack_Unwind_Resume调用