我花了几天时间解决这个问题。为了简便起见,我制作了一个小样本。
这是我的代码。
如您所见,在ListComponent.qml中,我有一个与后端模型绑定的listview。 因此,我在main.qml和模型中制作了2个ListComponent.qml实例。
我的要求是,如果我在cpp中有一个MassDataList,其中包含人员名称, 在ListView1中,我都需要以字母A开头;在ListView2中,我都需要以字母B开头。
代码示例如下:
main.qml
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
TextField {
x: 0
y: 0
onTextChanged: Test.setModel(text)
}
ListComponent {
id: component1
x: 26
y: 44
width: 100
height: 291
}
ListComponent {
id: component2
x: 163
y: 44
width: 100
height: 291
}
}
ListComponent.qml
import QtQuick 2.0
Item {
Rectangle {
id: rectangle
color: "#ffffff"
anchors.fill: parent
ListView {
id: listView
width: 200; height: 300
spacing: 5
model: Test.model
anchors.fill: parent
delegate: Item {
x: 5
width: 80
height: 40
Row {
id: row1
spacing: 10
Text {
text: modelData
font.bold: true
anchors.verticalCenter: parent.verticalCenter
}
}
}
}
}
}
C ++方面
TestModel-Test.h
#ifndef TEST_H
#define TEST_H
#include "QObject"
class Test: public QObject {
Q_OBJECT
Q_PROPERTY(QStringList model MEMBER m_model NOTIFY modelChanged)
QStringList m_model;
public slots:
void setModel(QString m) {
QStringList q;
for(int i=0;i<massList.length();i++)
{
if(massList.at(i).contains(m))
q.append(massList[i]);
}
//m_model = m.split(" ");
m_model = q;
modelChanged();
}
signals:
void modelChanged();
public:
Test();
QList<QString> massList;
};
#endif // TEST_H
Test.cpp
#include "test.h"
Test::Test()
{
massList.append("Anil");
massList.append("Athul");
massList.append("Aneesh");
massList.append("Ajay");
massList.append("Anoop");
massList.append("Bithu");
massList.append("Bineesh");
massList.append("Bineesh");
massList.append("Bejoy");
massList.append("Anirudh");
}
最后是main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "test.h"
#include "QQmlContext"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
Test t;
engine.rootContext()->setContextProperty("Test", &t);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
请帮助
根据Eyllanesc的建议,我尝试了以下示例中的代表小组。但是问题在于,对于每个过滤器,我需要创建不同的模型组。就我而言,这是不可能的。
我有一个GridView,其中ListViews作为委托项,并且我想要用于不同listViews的不同模型。
这是我尝试的示例委托组示例
/*
* Copyright 2014 ImaginativeThinking
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.0
import QtQml.Models 2.1
import QtQml.Models 2.1
ApplicationWindow {
title: qsTr("DelegateModel Sample 2")
width: 640
height: 600
visible: true
menuBar: MenuBar {
Menu {
title: qsTr("File")
MenuItem {
text: qsTr("Exit")
onTriggered: Qt.quit();
}
}
}
Item {
id: root
anchors.fill: parent
readonly property int rowHeight: 25
DelegateModel {
id: detailsDelegateModel
delegate: detailsDelegate
model: MyModel // This is a root context set in the main.cpp file.
groups: [
DelegateModelGroup {
includeByDefault: false
name: "detailsField"
}
]
filterOnGroup: "detailsField"
Component.onCompleted: {
var rowCount = MyModel.count;
items.remove(0,rowCount);
for( var i = 0;i < rowCount;i++ )
{
var entry = MyModel.get(i);
if(entry.role_details !== undefined) {
items.insert(entry, "detailsField");
}
}
}
}
Component {
id: detailsDelegate
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: root.rowHeight
color: "yellow"
border.color: "black"
Text {
text: role_details
anchors.centerIn: parent
}
}
}
DelegateModel {
id: displayDelegateModel
delegate: displayDelegate
model: MyModel
groups: [
DelegateModelGroup {
includeByDefault: false
name: "displayField"
}
]
filterOnGroup: "displayField"
Component.onCompleted: {
var rowCount = MyModel.count;
items.remove(0,rowCount);
for(var i = 0;i < rowCount;i++)
{
var entry = MyModel.get(i);
if(entry.role_display !== undefined){
items.insert(entry, "displayField");
}
}
}
}
Component{
id: displayDelegate
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: root.rowHeight
color: "green"
border.color: "black"
Text {
text: role_display
anchors.centerIn: parent
}
}
}
DelegateModel {
id: evenValueDelegateModel
delegate: valueDelegate
model: MyModel
groups: [
DelegateModelGroup {
includeByDefault: false
name: "evenNumbers"
}
]
filterOnGroup: "evenNumbers"
Component.onCompleted: {
var rowCount = MyModel.count;
items.remove(0,rowCount);
for( var i = 0;i < rowCount;i++ )
{
if ( MyModel.isEven(i) ) {
items.insert(MyModel.get(i), "evenNumbers");
}
}
}
}
Component{
id: valueDelegate
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: root.rowHeight
color: "lightblue"
border.color: "black"
Text {
text: role_value
anchors.centerIn: parent
}
}
}
Column{
id: theColumn
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: 10
height: childrenRect.height
spacing: 0
Text {
anchors.horizontalCenter: parent.horizontalCenter
width: 600
wrapMode: Text.WordWrap
text: "In this example we have a single model with 12 entries and via a Delegate Model Group we are filtering that data so that we can display a sub-set of it in different ListViews"
}
Item { width: 20; height: 20; }
Text {
text: "In this List View we are only showing the entries that have a details role."
}
ListView {
id: detailsListView
anchors.left: parent.left
anchors.right: parent.right
height: root.rowHeight * 5
model: detailsDelegateModel
}
Item { width: 20; height: 20; }
Text {
text: "In this List View we are only showing the entries that have a display role."
}
ListView {
id: displayListView
anchors.left: parent.left
anchors.right: parent.right
height: root.rowHeight * 4
model: displayDelegateModel
}
Item { width: 20; height: 20; }
Text {
text: "In this List View we are only showing the entries whose value are even."
}
ListView {
id: evenValueListView
anchors.left: parent.left
anchors.right: parent.right
height: root.rowHeight * 7
model: evenValueDelegateModel
}
}
}
}
具有以下型号。
标题为
/*
* Copyright 2014 ImaginativeThinking
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MYVIEWMODEL_H
#define MYVIEWMODEL_H
#include <QStandardItemModel>
#include <QObject>
class MyViewModel : public QStandardItemModel
{
Q_OBJECT
Q_PROPERTY( int count READ getRowCount() NOTIFY rowCountChanged() )
public:
/**
* @brief Defines a list of application-specific roles particually related to this view model's data model.
*
* Each item in the view model has a set of data elements associated with it, each with its own role.
* Roles are used by the view to indicate to the view model which type of data it needs. The roles
* defined in this enum are specific to this view models data model.
* @see <a href="http://qt-project.org/doc/qt-5.0/qtcore/qt.html#ItemDataRole-enum" style="font-weight:bold;">Qt::ItemDataRole</a>
*/
enum MyViewModel_Roles
{
MyViewModel_Roles_Display = Qt::UserRole + 1, /**< This role holds the display string for an entry in the model. */
MyViewModel_Roles_Details, /**< This role holds the details string for an entry in the model. **/
MyViewModel_Roles_KeyId, /**< This role holds the key id for an entry in the model. **/
MyViewModel_Roles_Value, /**< This role holds the value for an entry in the model. **/
};
/**
* @brief MyViewModel is the Constructor that will create an instance of this class
*/
MyViewModel();
/**
* @brief ~MyViewModel is the destructor that will clean up this object when its not needed anymore.
*/
virtual ~MyViewModel();
/**
* @brief Initializes the ViewModel and populates it with data
*/
void initialize();
/**
* @return A collection of the view models role names.
* @see MenuRoles
* @see <a href="http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html#roleNames" style="font-weight:bold;">QAbstractItemModel</a>
*/
virtual QHash<int,QByteArray> roleNames() const;
/**
* @param rowNumber is the index within the model for the item we want to check.
* @return Returns true if the entry's value role holds an even number.
*/
Q_INVOKABLE bool isEven( int rowNumber );
/**
* @param rowNumber specifies which row within the model the item we want to check is located.
* @return Returns a map that holds all the attributes about the item using the role names as the key.
* @note The return value is a key/value pair where the keys are available in QML so we can
* use the returned object to get any of the role information about the data (e.g. returnObject.role_display)
*/
Q_INVOKABLE QVariantMap get( int rowNumber ) const;
signals:
/**
* @brief rowCountChanged is emitted whenever the row count changes
*/
void rowCountChanged();
private slots:
/**
* @return Returns the number of rows in the model
*/
int getRowCount();
};
#endif // MYVIEWMODEL_H
cpp是
#include "MyViewModel.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
MyViewModel::MyViewModel()
{
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
MyViewModel::~MyViewModel()
{
this->clear();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QHash<int,QByteArray> MyViewModel::roleNames() const
{
// Maps the role names used in the QML to the role name enum used in the code behind.
QHash<int, QByteArray> roles;
roles[MyViewModel_Roles_Display] = "role_display";
roles[MyViewModel_Roles_Details] = "role_details";
roles[MyViewModel_Roles_KeyId] = "role_keyid";
roles[MyViewModel_Roles_Value] = "role_value";
return roles;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void MyViewModel::initialize()
{
auto root = this->invisibleRootItem();
QStandardItem* entry = new QStandardItem();
entry->setData("One", MyViewModel_Roles_Display );
entry->setData(0, MyViewModel_Roles_Value );
root->appendRow(entry);
entry = new QStandardItem();
entry->setData("One", MyViewModel_Roles_Display );
entry->setData(2, MyViewModel_Roles_Value );
root->appendRow(entry);
entry = new QStandardItem();
entry->setData("One", MyViewModel_Roles_Display );
entry->setData(3, MyViewModel_Roles_Value );
root->appendRow(entry);
entry = new QStandardItem();
entry->setData("One", MyViewModel_Roles_Display );
entry->setData(4, MyViewModel_Roles_Value );
root->appendRow(entry);
entry = new QStandardItem();
entry->setData("Two", MyViewModel_Roles_Details );
entry->setData(5, MyViewModel_Roles_Value );
root->appendRow(entry);
entry = new QStandardItem();
entry->setData("Three", MyViewModel_Roles_Details );
entry->setData(6, MyViewModel_Roles_Value );
root->appendRow(entry);
entry = new QStandardItem();
entry->setData("Four", MyViewModel_Roles_Details );
entry->setData(7, MyViewModel_Roles_Value );
root->appendRow(entry);
entry = new QStandardItem();
entry->setData("Five", MyViewModel_Roles_Details );
entry->setData(8, MyViewModel_Roles_Value );
root->appendRow(entry);
entry = new QStandardItem();
entry->setData("Six", MyViewModel_Roles_Details );
entry->setData(9, MyViewModel_Roles_Value );
root->appendRow(entry);
entry = new QStandardItem();
entry->setData("Seven", MyViewModel_Roles_KeyId );
entry->setData(10, MyViewModel_Roles_Value );
root->appendRow(entry);
entry = new QStandardItem();
entry->setData("Eight", MyViewModel_Roles_KeyId );
entry->setData(11, MyViewModel_Roles_Value );
root->appendRow(entry);
entry = new QStandardItem();
entry->setData("hello", MyViewModel_Roles_KeyId );
entry->setData(12, MyViewModel_Roles_Value );
root->appendRow(entry);
emit rowCountChanged();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int MyViewModel::getRowCount()
{
return this->rowCount();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool MyViewModel::isEven(int rowNumber)
{
bool ret( false );
if ( this->invisibleRootItem() != nullptr )
{
if ( this->invisibleRootItem()->rowCount() > rowNumber )
{
auto entry = this->invisibleRootItem()->child( rowNumber );
bool ok( false );
auto value = entry->data( MyViewModel_Roles::MyViewModel_Roles_Value ).toInt( &ok );
if ( ok )
{
if ( ( value % 2) == 0 )
{
ret = true;
}
}
}
}
return ret;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QVariantMap MyViewModel::get( int rowNumber ) const
{
// Create a map to hold all the role information about the data item in question
// Use the role names as the keys for the map so that the same referances can be
// used in the QML to get the data (i.e. role_display, role_value).
QVariantMap map;
QHash<int,QByteArray> roleName = roleNames();
foreach (int i, roleName.keys())
{
map[roleName.value(i)] = data( index( rowNumber,0 ), i );
}
return map;
}
答案 0 :(得分:0)
我使用提到的FilterGroups解决了这个问题。问题解决了。管理员,如何将其标记为已解决?