c++ - 如何将 C++ 中的 QStringList 显示到 QML ListView

标签 c++ qt listview qml qstringlistmodel

所以我是 Qt 的新手,我想提高我的 C++ 技能,所以我决定开始一个项目,我可以使用文本字段在 QStringList 中搜索项目。我让搜索功能正常工作,并且能够将搜索结果移动到另一个 QStringList 中,在那里我可以使用它在一个声明为“公共(public)插槽”的函数中向用户显示.

主要思想是,只要用户在文本字段中输入字符,列表就会自动更新,它已经这样做了。因此,我设法将结果列表放入 Slot 函数中,以便每次都能显示不同的列表,并且在文本字段中输入字符。


在我传递搜索结果列表的函数中,我尝试使用这个

m_context->setContextProperty("resultModel",QVariant::fromValue(m_resultList));

resultModel 是我在 QML 中的模型名称,m_resultList 是存储搜索结果的位置,用于在 ListView 中显示列表。我的程序可以编译,但在运行后崩溃。

所以,我真正的问题是:有什么方法可以将不在 main.cpp 中的 C++ QStringList 显示到 QML ListView 中?

我要求它不在 main 中的原因是因为我试图在 main.cpp 中使用上面的同一行和硬编码的 QStringList 并且列表能够显示,所以它不在主体中肯定有问题。也因为我将无法使用 SearchClass 中的插槽功能来自动更新。


main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDebug>
#include "searchclass.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    qmlRegisterType<SearchClass>("b9c.backend", 1, 0, "BackEnd");

    QQmlApplicationEngine engine;

    SearchClass obj;

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    QQmlContext *context = engine.rootContext();

    obj.getContext(context);

    //the line below works if provided with a qstringlist

    //context->setContextProperty("resultModel", QVariant::fromValue(resultList));

    return app.exec();
}

搜索类.h

#ifndef SEARCHCLASS_H
#define SEARCHCLASS_H

#include <QObject>
#include <QQmlContext>

class SearchClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString userSearch READ userSearch WRITE setUserSearch NOTIFY userSearchChanged)

public:
    SearchClass(QObject *parent = 0);

    QStringList resultList;

    QString userSearch();
    void setUserSearch(QString &userSearch);

    void getFilenameAndInput(QString inputString);
    QString CompareInputAndFilename(QString inputString, QString filename);
    QStringList getFileName();

    //get context
    void getContext(QQmlContext *context);

signals:
    void userSearchChanged();

public slots:
    void setUserSearch();

private:
    QStringList m_resultList;
    QString m_userSearch;
    QQmlContext* m_context;
};

#endif // SEARCHCLASS_H

搜索类.cpp

#include "searchclass.h"
#include <QDebug>
#include <QQmlContext>
#include <QGuiApplication>
#include <QQmlApplicationEngine>


SearchClass::SearchClass(QObject *parent) : QObject(parent)
{
    connect(this, SIGNAL(userSearchChanged()), this, SLOT(setUserSearch()));
}

//the result should be displayed in this SLOT when ever the user types in a character into the textfield
void SearchClass::setUserSearch(){

    qDebug() << "SLOT: " << m_resultList;

//The line below makes the program crash. It works when implemented in the main.cpp
//    m_context->setContextProperty("resultModel", QVariant::fromValue(m_resultList));

}

QString SearchClass::userSearch()
{
    return m_userSearch;
}

void SearchClass::setUserSearch(QString &userSearch)
{
    if (userSearch == m_userSearch)
        return;

    m_userSearch = userSearch;

    qDebug() << "Input: " <<m_userSearch;

    getFilenameAndInput(m_userSearch);

    emit userSearchChanged();
}

QStringList SearchClass::getFileName(){

//Returns the items that will be searched for...

}

void SearchClass::getFilenameAndInput(QString inputString){

//Puts the search results into class variable m_resultList...

    m_resultList = resultList;

}

QString SearchClass::CompareInputAndFilename(QString inputString, QString filename){

//Search processing... 

}

//gets context to use setProperty in the above signal, but it crashes
void SearchClass::getContext(QQmlContext *context){

    m_context = context;

}

ma​​in.qml

import QtQuick 2.6
import QtQuick.Controls 2.0
import b9c.backend 1.0
import QtQuick.Window 2.2


ApplicationWindow {
    id: root
    width: 300
    height: 480
    visible: true
    BackEnd { id: backend }

    TextField {
        id: txtfield
        text: backend.userSearch
        placeholderText: qsTr("Search...")
        width: parent.width

        onTextChanged: backend.userSearch = text
    }

    ListView {
        id:view
        height: parent.height
        width: parent.width
        y: 5 + txtfield.height
        model: resultModel

        delegate: Rectangle {
            border.color: "lightblue"
            height: 25
            width: parent.width
            Text {
                anchors.centerIn: parent
                text: modelData
            }
        }
    }

}

最佳答案

你做错了。百般。您甚至可以将实际设置上下文的函数命名为 getContext()

m_resultList 从未设置为您提供的代码中的任何内容。因此无法告诉您应用程序崩溃的原因,因为实际数据是个谜。

您还有一个 QObject 派生类 - 您的 SearchClass。因此,您应该将其公开为上下文属性,然后通过实现为 SearchClassQ_PROPERTY 将字符串列表连接到 QML。

这是一个简单的例子:

// the equivalent of your SearchClass
class Test : public QObject {
    Q_OBJECT
    Q_PROPERTY(QStringList model MEMBER m_model NOTIFY modelChanged)
    QStringList m_model;
  public slots:
    void setModel(QString m) {
      m_model = m.split(" ");
      modelChanged();
    }
  signals:
    void modelChanged();
};

// in main.cpp
  Test t;
  engine.rootContext()->setContextProperty("Test", &t);

// in main.qml
Column {
    TextField {
      onTextChanged: Test.setModel(text)
    }
    ListView {
      width: 200; height: 300
      spacing: 5    
      model: Test.model
      delegate: Rectangle {
        height: 25
        width: 200
        color: "lightgray"
        Text { text: modelData; anchors.centerIn: parent }
      }
    }
  }

当您键入时,文本字符串被发送到 Test::setModel(),然后它将其拆分为以空格分隔的标记并设置 QStringList,用作 ListView 的模型源。

关于c++ - 如何将 C++ 中的 QStringList 显示到 QML ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45377676/

相关文章:

c++ - QString 到 windows BYTE

java - Android 复选框 Listview 回收导致意外的框检查

java - 处理 onClick 事件时 getView 出现空指针异常

C++ 使用 ostringstream move 语义

C++ 3D 模型动画库?

c++ - 优化C++中的成员变量顺序

c++ - Qt4 槽和信号 : Qt4 has trouble finding the signal

Qt 应用程序在没有调试信息的情况下立即崩溃。我如何追踪问题?

android - 在 Flutter 的垂直列表中添加动态高度水平 ListView

c++ - 如何循环 n 次,在 xml 文件中每个循环一个级别