Place multiple items in one Cell in a GridView
-
Hi,
is it possible to place multiple items in on Cell in a GridView? I'm using a QAbstractListModel to set the data.
My Model:
@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QAbstractListModel>
#include <QStringList>//![0]
class Timeline
{
public:
Timeline(const QString &deviceImage, const QString &euro, const QString &kwh, const QString &time, const bool elementVisible);
Timeline(const QString &date, const bool &elementVisible);
Timeline(const bool &elementVisible);
//![0]QString deviceImage() const; QString euro() const; QString kwh() const; QString time() const; QString date() const; bool elementVisible() const;
private:
QString m_deviceImage;
QString m_euro;
QString m_kwh;
QString m_time;
QString m_date;
bool m_elementVisible;//![1]
};
class TimelineModel : public QAbstractListModel
{
Q_OBJECT
public:
enum TimelineRoles {
DeviceImageRole = Qt::UserRole + 1,
EuroRole,
KwhRole,
TimeRole,
DateRole,
ElementVisibleRole
};TimelineModel(QObject *parent = 0); //![1] void addDevice(const Timeline &device); int rowCount(const QModelIndex & parent = QModelIndex()) const; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
protected:
QHash<int, QByteArray> roleNames() const;
private:
QList<Timeline> m_devices;
//![2]
};
//![2]
@My GridView:
@
import QtQuick 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.1Rectangle {
anchors.fill: parentGridView { id: gridView1 anchors.fill: parent cellWidth: grid.width/3 cellHeight: grid.height/3 model: timelineModel delegate: Item { x: 5 height: 50 Column { spacing: 20 Button { id: deviceImageButton; iconSource: deviceImage; visible: elementVisible; anchors.horizontalCenter: parent.horizontalCenter; onClicked: setVisibleEffect(euroText, kwhText, timeText) } Text { id: euroText; text: euro; font.pointSize: 12; visible: false; anchors.horizontalCenter: parent.horizontalCenter } Text { id: kwhText; text: kwh; visible: false; font.pointSize: 12; anchors.horizontalCenter: parent.horizontalCenter } Text { id: timeText; text: time; visible: false; font.pointSize: 12; anchors.horizontalCenter: parent.horizontalCenter } Rectangle { id: dateRectangle color: "#808080" Text { id: dataText; text: date; visible: true; anchors.horizontalCenter: parent.horizontalCenter; anchors.verticalCenter: parent.horizontalCenter; } // width: childrenRect.width // height: childrenRect.height } } } }
}
@My first idea is to solve this with QList inside the TimelineModel? Or any other approaches?
Cheers
-
Depends on what you want delegate can be what ever you want and derived from Item like Rectangle or whatever.
-
I want to place multiple buttons and text in one cell. How can I do this? Everytime if I place more than one button than the button gets in the next cell and not in the same cell.
Any Ideas?
-
Do I have to modify my qml dynamically or can I handle this with my model?
-
Sorry i'm not really understand what you want or what's the problem. maybe this helps:
@
Rectangle {
width: 300; height: 200GridView { id: grid anchors.fill: parent cellWidth: 80; cellHeight: 80 model: ListModel { ListElement { name: "Jim Williams" portrait: "pics/portrait.png" button_1: "1_1" button_2: "1_2" button_3: "2_3" } ListElement { name: "John Brown" portrait: "pics/portrait.png" button_1: "2_1" button_2: "2_2" button_3: "2_3" } ListElement { name: "Bill Smyth" portrait: "pics/portrait.png" button_1: "3_1" button_2: "3_2" button_3: "3_3" } ListElement { name: "Sam Wise" portrait: "pics/portrait.png" button_1: "4_1" button_2: "4_2" button_3: "4_3" } } delegate: Item { width: grid.cellWidth; height: grid.cellHeight Column { anchors.fill: parent Image { source: portrait; anchors.horizontalCenter: parent.horizontalCenter } Text { text: name; anchors.horizontalCenter: parent.horizontalCenter } Button { text: button_1; onClicked: {console.log(button_1);}} Button { text: button_2; onClicked: {console.log(button_2);}} Button { text: button_3; onClicked: {console.log(button_3);}} } } highlight: Rectangle { color: "lightsteelblue"; radius: 5 } focus: true } }
@
-
But what is if you want to place in one cell for example 3 buttons and in the next cell for example 5 buttons... Can you handle this with your model oder do I have to change my qml every time dynamically?
Thanks
-
The model never handle anything. You have dynamic data, so you need dynamic element creation. My source is only a solution if your model items have the same data structure. You see it, ListElement have always the same properties only the values are different. You are a German guy right?
-
Right! How can I use dynamic element creation? Is this possible with repeater?
-
Take a look in this forum or use "google":https://www.google.de/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=qml+dynamic+object+creation. And please add [SOLVED] to the titles of all your solved threads! I'm also from Germany :)
-
Thanks dasRicardo!
I extend my code with a javascript to set my elements dynamically. But how can I set my button and my text in my gridview in one cell instead of placing them in separate cells?
This is what I want:
I Button I
I Text I
I Text I
I Text I
I
I Button I
I Text I
I Text I
I Text IThis is how it looks like at the moment:
I Button I I Button I
I Text I I Text I
I Text I I Text I
I Text I I Text I
my main.cpp
@
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include <client.h>
#include <timeline.h>#include <QQmlComponent>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);QQmlApplicationEngine engine; TimelineModel model; model.addDevice(Timeline("content/image/devices/water_heater.png", "1,70 €", "0,80 kWh", "16:00 - 16:45", true)); model.addDevice(Timeline("content/image/devices/tv", "1,70 €", "0,80 kWh", "16:00 - 16:45", true)); model.addDevice(Timeline("content/image/devices/device_placeholder.png", "1,70 €", "0,80 kWh", "16:00 - 16:45", true)); model.addDevice(Timeline("12 August", false));
engine.rootContext()->setContextProperty("timelineModel", &model); engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
return app.exec();
}
@my timeline.qml:
@
import QtQuick 2.2
import QtQuick.Dialogs 1.1
import QtQuick.Controls 1.1
import "componentCreation.js" as MyScriptRectangle {
id: timelineRectangle
anchors.fill: parent
visible: true
Loader {
id: qmlloader
// anchors.fill: parent
z: 1
}Rectangle { id: rectangle1 x: parent.width/2 - 10; width: 20 height: parent.height; color: "#000000" clip: false anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom anchors.top: parent.top } Component { id: timelineDelegate Item { width: grid.cellWidth; height: grid.cellHeight Column { id: timelineColumn anchors.fill: parent spacing: 20 Component.onCompleted: MyScript.createSpriteObjects(timelineColumn); } } } GridView { id: grid flickableDirection: Flickable.AutoFlickDirection anchors.fill: parent cellWidth: grid.width/3 cellHeight: grid.height/3 anchors.margins: 100 delegate: timelineDelegate model: timelineModel }
}
@my componentCreation.js:
@
var component;
var sprite;function createSpriteObjects(timeParent) {
component = Qt.createComponent("TimelineItems.qml");
if (component.status == Component.Ready) {
sprite = component.createObject(timeParent);
}if (sprite == null) { // Error Handling console.log("Error creating object"); console.log("component: " + component.error); }
}
@my TimelineItems.qml
@
Rectangle {Column { Button {text: "Button"; anchors.horizontalCenter: parent.horizontalCenter} Text {text: "euro" } Text {text: "kwh" } Text {text: "time" } }
}
@