【问题标题】:Populate ComboBox from QList<QObject*>从 QList<QObject*> 填充 ComboBox
【发布时间】: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 中做任何其他事情

标签: qt qml


【解决方案1】:

你有两个问题:

  1. 您的 stockModel 属性应该是 NOTIFYable,这意味着您应该使用例如定义属性Q_PROPERTY(QList&lt;QObject*&gt; stockModel READ stockModel NOTIFY stockModelChanged) 并在 DbCon 类中提供 void stockModelChanged(const QList&lt;QObject *&gt; &amp;) 信号。
  2. 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() 提供了
猜你喜欢
  • 2013-11-03
  • 1970-01-01
  • 2014-03-06
  • 1970-01-01
  • 2019-10-23
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
相关资源
最近更新 更多