Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Делегат в Qml


Автор: vlarry 9.4.2016, 08:30
Добрый день, форумчане.

Есть элемент модели такого типа:
Код

ListElement
{
     type_item:    "rectangle"
     color_item:   "yellow"
     opacity_item: 0.5

     border_item:
     [
             ListElement { color: "red" },
             ListElement { width: 5 }
     ]

     topLeft_item:
     [
             ListElement { lat: 47.94494 },
             ListElement { lng: 33.43207 }
     ]

     bottomRight_item:
     [
             ListElement { lat: 47.95 },
             ListElement { lng: 33.45 }
     ]
}


свойство type_item может иметь разные значения (типы) и соответственно в зависимости от типа должна отображаться соответствующая фигура. Как можно сделать такой делегат?

Если для определенного типа, то проблем нет:
Код

Component
{
    id: objectDelegate

    MapRectangle
    {
        color:   color_item
        opacity: opacity_item

        border.color: border_item.get(0).color
        border.width: border_item.get(1).width

        topLeft:     QtPositioning.coordinate(topLeft_item.get(0).lat, topLeft_item.get(1).lng)
        bottomRight: QtPositioning.coordinate(bottomRight_item.get(0).lat, bottomRight_item.get(1).lng)

        Component.onCompleted:
        {
            console.log(topLeft + ", " + bottomRight);
        }
    }
}


А как в зависимости от типа создавать динамически? Пробовал по разному, но ничего не получилось.
В Qml знаний маловато...
Спасибо.

Автор: ss 10.4.2016, 21:01
Код


ListView{

            width: 100
            height: 150
            model: dataModel

            delegate:Item{
                width: 40
                height: 25
                id: rectDelegateItem

                Rectangle{
                    anchors.fill: rectDelegateItem
                    color: "orange"
                    visible: model.type_item === "rectangle" ? true : false
                }
                Button{
                    anchors.fill: rectDelegateItem
                    visible: model.type_item === "button" ? true : false
                }
            }
        }


Автор: vlarry 11.4.2016, 12:32
Спасибо за ответ. Попробовал, но не получилось...
Сделал так:

Код

Component
{
    id: objectDelegate

    MapRectangle
    {
        color:   color_item
        opacity: opacity_item

        border.color: border_item.get(0).color
        border.width: border_item.get(1).width

        topLeft:     QtPositioning.coordinate(topLeft_item.get(0).lat, topLeft_item.get(1).lng)
        bottomRight: QtPositioning.coordinate(bottomRight_item.get(0).lat, bottomRight_item.get(1).lng)

        visible: model.type_item === "rectangle"?true:false
    }

    MapCircle
    {
        color:   color_item
        opacity: opacity_item

        border.color: border_item.get(0).color
        border.width: border_item.get(1).width

        center: QtPositioning.coordinate(center_item.get(0).lat, center_item.get(1).lng)
        radius: radius_item

        visible: model.type_item === "circle"?true:false
    }
}


в консоли выводит: Invalid component body specification

Автор: vlarry 11.4.2016, 12:53
Судя по документации, то так и не получится, т.к. MapItemView должен содержать ровно один корневой объект:
Цитата

The Component must contain exactly one MapItem -derived object as the root object.

Как это можно обойти?
Спасибо.

Автор: vlarry 11.4.2016, 13:22
Если попытаться, все MapItem обернуть в один Item {}, то пишет в консоли, что такой итем не поддерживается...У кого есть какие идеи? Спасибо.

Автор: vlarry 11.4.2016, 13:54
Обернул через Item:

Код

Item
{
    id: _delegate

    property Component objectDelegate

    Component
    {
        id: delegateRectangle

        MapRectangle
        {
            color:   objectsModel.color_item
            opacity: objectsModel.opacity_item

            border.color: objectsModel.border_item.get(0).color
            border.width: objectsModel.border_item.get(1).width

            topLeft:     QtPositioning.coordinate(objectsModel.topLeft_item.get(0).lat, objectsModel.topLeft_item.get(1).lng)
            bottomRight: QtPositioning.coordinate(objectsModel.bottomRight_item.get(0).lat, objectsModel.bottomRight_item.get(1).lng)
        }
    }

    Component
    {
        id: delegateCircle

        MapCircle
        {
            color:   objectsModel.color_item
            opacity: objectsModel.opacity_item

            border.color: objectsModel.border_item.get(0).color
            border.width: objectsModel.border_item.get(1).width

            center: QtPositioning.coordinate(objectsModel.center_item.get(0).lat, objectsModel.center_item.get(1).lng)
            radius: objectsModel.radius_item
        }
    }

    Component.onCompleted:
    {
        if(objectsModel.type_item === "rectangle")
            objectDelegate = delegateRectangle;
        else if(objectsModel.type_item === "circle")
            objectDelegate = delegateCircle;

        console.log(objectsModel.type_item); // выводит в консоли "undefined"
    }
}


Как теперь добраться до свойства модели?

Автор: ss 11.4.2016, 22:28
Цитата

 Попробовал, но не получилось...


а что говорит ?


попробуй в строке visible: model.type_item === "rectangle" ? true : false
убрать слово "model."
вот так visible: type_item === "rectangle" ? true : false




делегат через Component

MyDelegate.qml
Код

import QtQuick 2.0
import QtQuick.Controls 1.3

Component{
    id: rectDelegateItem
Row{

    Rectangle{
        color: "orange"
        width: 40
        height: 25
        visible: mcolor !== "Button" ? true : false
    }

    Button{
        text: "button"
        visible: mcolor === "Button" ? true : false
    }
}
}



main.qml
Код

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Dialogs 1.2

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")


    MainForm {
        anchors.fill: parent


        ListModel {
                id: dataModel

                ListElement {
                    mcolor: "Button"
                    mtext: "first"
                }
                ListElement {
                    mcolor: "Button"
                    mtext: "second"
                }
                ListElement {
                    mcolor: "Button"
                    mtext: "third"
                }
                ListElement {
                    mcolor: "tomato"
                    mtext: "fourth"
                }
            }

        ListView{

            id: lview
            width: 100
            height: 150
            model: dataModel
            delegate: MyDelegate{}
        }//ListView
    }

}



результат

Автор: vlarry 12.4.2016, 09:21
С ListView и у меня работает. В проекте я использую вид MapItemView и он не поддерживает Item. 

Цитата

а что говорит ?


Говорит: 
Цитата

QDeclarativeGeoMapItemView map item delegate is of unsupported type.


Пока так и не получилось, то что хотел сделать...а надо smile 

Автор: vlarry 12.4.2016, 09:48
В старом модуле QtMobility был такой тип как MapGroup, где можно было создать группу из итемов, а в QtLocation 5.6 ничего подобного не нашел...как эмулировать такую группу?! Зачем убирать полезное...непонятная политика...

Автор: vlarry 18.4.2016, 16:41
Добрый день.
Нашел все-таки как выводить любой объект, но теперь не знаю как обновить данные фигуры.
Код


MapItemView
{
    id:       objectsView
    model:    objectsModel

    delegate: MapQuickItem
    {
        id: quickItem

        Component.onCompleted:
        {
            console.log("type: ", type_item);

            if(type_item == "circle")
            {
                var lat    = center_item.get(0).lat;
                var lng    = center_item.get(1).lng;
                var center = QtPositioning.coordinate(lat, lng);

                sourceItem             = itemGreen;
                itemGreen.center       = center;
                itemGreen.radius       = radius_item;
                itemGreen.color        = color_item;
                itemGreen.border.color = border_item.get(0).color;
                itemGreen.border.width = border_item.get(1).width;

                console.log("center: ", itemGreen.center, ", radius: ", itemGreen.radius);
            }
        }
    }
}

MapCircle
{
    id: itemGreen

    Component.onCompleted:
    {
        console.log("circle green center: ", itemGreen.center, ", radius: ", itemGreen.radius);
    }
}


В консоли после 
Код

console.log("circle green center: ", itemGreen.center, ", radius: ", itemGreen.radius);

выводит пустые данные, т.е. circle создается раньше, чем считываются данные из модели. Как можно itemGreen обновить после обновления данных итема?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)