从 QList<QObject*> 填充 ComboBox

Posted

技术标签:

【中文标题】从 QList<QObject*> 填充 ComboBox【英文标题】:Populate ComboBox from QList<QObject*> 【发布时间】:2016-12-14 18:46:58 【问题描述】:

我正在关注网络上的一个示例来填充组合框,但它对我来说不起作用,我不知道为什么!。我有两个类stockDbConstock 具有三个私有字段以及公共访问器和修改器。 DbCon 有一个Q_Property 和两个公共函数,一个返回数据库连接,另一个创建并返回stock 列表作为QList&lt;QObject*&gt;。在main.cpp 中,我创建了一个名为“data”的上下文属性,用于从QML 访问DbCon

main.qml我有

....
ComboBox
        model: data.stockModel
        textRole: "code"
 
....  

在 main.cpp 中

DbCon db;
engine.rootContext()->setContextProperty("data", &db);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

在 dbcon.h 中

class DbCon:public QObject

    Q_OBJECT
    Q_PROPERTY(QList<QObject*> stockModel READ stockModel)

public:
    explicit DbCon(QObject *parent = 0);
    QSqlDatabase db();
    QList<QObject*> stockModel();
;

QList&lt;QObject*&gt; stockModel()dbcon.h的实现中

QList<QObject*> data;
....
while (query.next()) 
    stock *s = new stock();
    ....
    data.append(s);

return data;

有现货.h

class stock : public QObject

    Q_OBJECT
private:
    QString m_name;
    QString m_code;
    int m_id;

public:
    explicit stock(QObject *parent = 0);
    QString name();
    void setname(QString &name);
    QString code();
    void setcode(QString &code);
    int id();
    void setid(int &id);
;

当我运行应用程序时,我在应用程序输出中收到以下消息

QQmlExpression:表达式 qrc:/main.qml:16:20 依赖于不可通知​​的属性: QQuickComboBox::数据

我在组合框中没有得到任何东西!

如果我以这种方式在main.cpp 中创建另一个上下文属性

engine.rootContext()->setContextProperty("myModel", QVariant::fromValue(data));

并将myModel 设置为组合框的模型,它工作正常。但我想这样做是因为onCurrentIndexChanged 我将调用另一个函数,该函数为另一个qml 文件的TableView 返回另一个QList&lt;QObject*&gt;


编辑:条目 qml

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 2.0

Window 
    visible: true
    width:600
    height:600
    property string contentSource

    Column
        spacing:10
        ComboBox
            model: data.stockModel
            textRole: "code"
        
        Loader 
            id: content
            width: parent.width
            height:400
        
        Row
            spacing:10
            Button
                text: "Page1"
                onClicked: content.source = "Page1.qml"
            
            Button
                text: "Page2"
                onClicked: content.source = "Page2.qml"
            
        
    


通过将main.cpp 中的data 更改为dataStore 并将data.stockModel 更改为main.qml 中的dataStore.stockModel 我得到以下错误

file:///C:/Qt/Qt5.7.0/5.7/mingw53_32/qml/QtQuick/Controls.2/ComboBox.qml:62:15:无法将[未定义]分配给QString

【问题讨论】:

QML 中的“数据”是什么?它是如何定义的? @AlexanderVX 不是指向DbCon 的指针吗?它在main.cpp 中定义,如“in main.cpp”部分所示。 更好地显示整个 QML 部分。 知道了。数据是什么?在 QML 中,该 ComboBox 类型的数据继承自 Item: data : list 这不是真正的模型吗? @AlexanderVX 我在底部添加了整个 qml。它以这种方式适用于 QString、void 函数等。除了在 data. 之后指定函数()的名称或 QString 类型的 Q_PROPERY 的名称之外,我无需在 qml 中做任何其他事情 【参考方案1】:

你有两个问题:

    您的 stockModel 属性应该是 NOTIFYable,这意味着您应该使用例如定义属性Q_PROPERTY(QList&lt;QObject*&gt; stockModel READ stockModel NOTIFY stockModelChanged) 并在 DbCon 类中提供 void stockModelChanged(const QList&lt;QObject *&gt; &amp;) 信号。 stock::name() 也必须是一个属性,因此您需要使用 Q_PROPERTY(QString name READ name NOTIFY nameChanged) 声明它,并在 stock 类中提供 void nameChanged(const QString &amp;) 信号。

【讨论】:

如果我不参数化 stockModelChangednameChanged,它也可以工作。在这种情况下,我可以使用nameChanged() 而不是nameChanged(const QString &amp;)。在任何情况下我都无法避免函数中发出信号的参数? 取决于信号将连接到的功能。信号nameChanged(const QString &amp;) 既可以连接到带有const QString &amp; 参数的函数,也可以连接到根本不带任何参数的函数。看起来 QML 对信号本身的值不感兴趣,而是使用 getter 来检索它。 可能 qml 需要在某处发出信号以调用 getter @E4z9。在name 的设置器中,我通过写emit nameChanged() 提供了

以上是关于从 QList<QObject*> 填充 ComboBox的主要内容,如果未能解决你的问题,请参考以下文章

QObject 使用 setParent() 将 QList 设置为父级

QList<int> 不能用作Repeater 的模型

迭代作为 QList<int> 的 QVariant?

QML - 访问存储在 QList 中的 QObject 类属性

从 qml 编辑 QObject 属性

QObject::connect: 没有这样的信号运行时警告 - 找不到原因