Qt ListView 不显示 C++ 模型内容

Posted

技术标签:

【中文标题】Qt ListView 不显示 C++ 模型内容【英文标题】:Qt ListView doesn't show C++ model content 【发布时间】:2018-01-19 21:17:39 【问题描述】:

我正在使用 QML ListView 在 C++ 中创建一个 QList 来显示它。应用程序运行没有错误,但 ListView 顽固地保持为空。

QML 将为每个列表项的存在显示一个矩形。 我通过在 QML 中创建一个列表来检查 UI 代码。 对于 QML 创建的列表,它会正确显示。

这是我的 QML:

import Processes 1.0
...
ListView 
    id: qInterfaceList
    height: parent.height;
    width: parent.width;
    model: myModel
    orientation: ListView.Vertical
    delegate:
        Rectangle 
            height: 30;
            width: 120;
            border.color: "red"
            border.width: 3
        

创建和注册列表对象的 C++ 代码:

// Register C++ classes as a QML type named Processes (version 1.0)
qmlRegisterType<Process>("Processes", 1, 0, "Process");

QQmlApplicationEngine engine;

// read the configuration file
Config conf;
if ( conf.read() )

    QQmlContext* ctxt = engine.rootContext();
    if ( ctxt )
    
        qDebug()
            << "--- conf.Interfaces: "
            << conf.Interfaces.length()
            ;
        ConfigInterface c;
        QVariant v = QVariant::fromValue( conf.Interfaces );
        qDebug()
            << "--- ConfigInterface: "
            << v
            << "--- typeName: "
            << v.typeName()
            ;
        ctxt->setContextProperty("myModel", QVariant::fromValue( conf.Interfaces ));
    


engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
    return -1;
return app.exec();

为了调试,我从 C++ 和 QML 输出有关列表的信息: 在 C++ 中,列表项的计数是正确的。 在 C++ 中,到 QVariant 的转换是有效的。 在 QML 中,它会看到已定义的列表。

调试输出:

Debugging starts
--- conf.Interfaces:  65
--- ConfigInterface:  QVariant(QList<ConfigInterface*>, ) --- typeName:  QList<ConfigInterface*>
qml: myModel: QVariant(QList<ConfigInterface*>)
Debugging has finished

有什么想法或者如何调试它?

谢谢

编辑:这是用作列表项的类

类声明:

class ConfigInterface : public QObject

    Q_OBJECT

    Q_PROPERTY(QString sql READ getTag WRITE setTag NOTIFY tagChanged)
    Q_PROPERTY(QString description READ getDescription WRITE setDescription NOTIFY descriptionChanged)
public:
    /*explicit*/ ConfigInterface();
    /*explicit*/ ConfigInterface(QObject *parent);
    ~ConfigInterface();

    // Copy constructor needed because these are copied when added to a QList
    ConfigInterface(const ConfigInterface &p2) _tag = p2._tag; _description = p2._description; 

    QString getDescription() const;
    void setDescription(QString&);

    QString getTag() const;
    void setTag(QString&);

signals:
    void tagChanged(QString);
    void descriptionChanged(QString);

public:
    QString _tag;
    QString _description;
    QString QueryTemplate;
    QString ConnectString;
    QString MinimumId;
;

Q_DECLARE_METATYPE(ConfigInterface*)

C++ 代码:

ConfigInterface::ConfigInterface()
    : QObject( nullptr )



ConfigInterface::ConfigInterface(QObject* parent)
    : QObject(parent)



ConfigInterface::~ConfigInterface()



QString ConfigInterface::getTag() const

    return _tag;

void ConfigInterface::setTag(QString& str)

    _tag = str;
    emit tagChanged(_tag);

【问题讨论】:

ConfigInterface是继承自QObject的类? 源自QObject 你可以展示 ConfigInterface 类。 已编辑。课程代码显示在帖子底部。感谢您的帮助:) 【参考方案1】:

主要问题是因为它有一个ConfigInterface *的列表,根据文档中提供的examples应该是一个QObject *的列表:

class Config
    [...]
public:
    QList<QObject *> Interfaces;
    [...]
;

除此之外,您还应该收到以下警告:

/..../configinterface.h:17: warning: base class ‘class QObject’ should be explicitly initialized in the copy constructor [-Wextra]
     ConfigInterface(const ConfigInterface &p2) _tag = p2._tag; _description = p2._description; 
     ^~~~~~~~~~~~~~~

这是因为QObject 及其派生类不能有复制构造函数或赋值运算符,更多信息请阅读以下内容:

http://doc.qt.io/qt-5/qobject.html#no-copy-constructor-or-assignment-operator

另一个改进是两个构造函数只能合并为一个,最终它们的类可以具有以下结构:

configinterface.h

#ifndef CONFIGINTERFACE_H
#define CONFIGINTERFACE_H

#include <QObject>

class ConfigInterface : public QObject

    Q_OBJECT

    Q_PROPERTY(QString sql READ getTag WRITE setTag NOTIFY tagChanged)
    Q_PROPERTY(QString description READ getDescription WRITE setDescription NOTIFY descriptionChanged)
public:
    ConfigInterface(QObject *parent=Q_NULLPTR);
    ~ConfigInterface();

    QString getTag() const;
    void setTag(const QString &tag);
    QString getDescription() const;
    void setDescription(const QString &description);

signals:
    void tagChanged(QString);
    void descriptionChanged(QString);

private:
    QString _tag;
    QString _description;
    QString QueryTemplate;
    QString ConnectString;
    QString MinimumId;
;

#endif // CONFIGINTERFACE_H

configinterface.cpp

#include "configinterface.h"

ConfigInterface::ConfigInterface(QObject* parent)
    : QObject(parent)



ConfigInterface::~ConfigInterface()



QString ConfigInterface::getDescription() const

    return _description;


void ConfigInterface::setDescription(const QString &description)

    if(_description == description)
        return;
    emit descriptionChanged(description);
    _description = description;


QString ConfigInterface::getTag() const

    return _tag;


void ConfigInterface::setTag(const QString &tag)

    if(tag == _tag)
        return;
    emit tagChanged(tag);
    _tag = tag;

【讨论】:

我的类是从 QObject 派生的。 Qt 示例显示了用作 QML 模型的派生对象的 QList。 Q_DECLARE_METATYPE 的文档说“可以注册任何具有公共默认构造函数、公共复制构造函数和公共析构函数的类或结构”。这与您的陈述冲突,我不应该有一个复制构造函数。我很怀疑,但我一定会试试你的代码。 @Jay 如果类继承自 QObject 则不需要使用 Q_DECLARE_METATYPE,也可以查看这个问题***.com/questions/47803531/… @Jay 我的测试的完整例子可以在github.com/eyllanesc/***/tree/master/48349672找到 哇!感谢您的所有努力。如果可以的话,我会给你两个赞成票

以上是关于Qt ListView 不显示 C++ 模型内容的主要内容,如果未能解决你的问题,请参考以下文章

模型中的 Qt 模型?

这种将 C++ QStringList 加载为 QML ListView 模型的方式有啥问题?

28.qt quick-ListView高仿微信好友列表和聊天列表

Qt中使用QML和Listview的问题

QT/QML 数据模型

QT/QML:模型没有数据时如何显示消息