QM材质纸莎草MenuField

时间:2019-03-12 01:55:58

标签: qt

我目前在用QAbstractListModel填充纸莎草菜单字段或ComboBox的QML材料时遇到问题。

有人知道有一种方法可以显示数据并预定义qml材质的纸莎草纸菜单字段给定值的C ++模型吗?

示例数据库

表域

字段:

  • id
  • 名称

这里是使用的类:

                    **domaine.h**

                    #ifndef DOMAINE_H
                    #define DOMAINE_H

                    #include <QString>
                    #include "gesprojet_global.h"
                    class GESPROJETSHARED_EXPORT Domaine
                    {

                    public:
                        explicit  Domaine(const QString& name = "" );

                        int id() const;
                        void setId(int id);
                        QString name() const;
                        void setName(const QString& name);

                    private:
                        int mId;
                        QString mName;
                    };

                    #endif // DOMAINE_H

                    **domaine.cpp**

                    #include "domaine.h"

                Domaine::Domaine(const QString &name) :
                            mId(-1),
                            mName(name)
                {
                }

                int Domaine::id() const
                {
                    return  mId;
                }

                void Domaine::setId(int id)
                {
                   mId = id ;
                }

                QString Domaine::name() const
                {
                    return  mName;
                }

                void Domaine::setName(const QString& name)
                {
                    mName = name;
                }


            // domaineModel.h



            #ifndef DOMAINEMODEL_H
            #define DOMAINEMODEL_H

            #include <QAbstractListModel>
            #include <QHash>
            #include <vector>
            #include <memory>

            #include "gesprojet_global.h"
            #include "domaine.h"
            #include "databasemanager.h"


            class GESPROJETSHARED_EXPORT DomaineModel : public QAbstractListModel
            {
                Q_OBJECT
            public:

                enum Roles {
                           IdRole = Qt::UserRole + 1,
                           NameRole,
                };

                DomaineModel(QObject * parent = 0);

                QModelIndex addDomaine(const Domaine& domaine);
                Q_INVOKABLE void addDomaineFromName(const QString& name);
                Q_INVOKABLE void rename(int row, const QString& name);

                int rowCount(const QModelIndex& index = QModelIndex()) const override;
                Q_INVOKABLE QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
                bool setData(const QModelIndex& index, const QVariant& value, int role) override;
               Q_INVOKABLE bool removeRows(int row, int count, const QModelIndex& parent) override;
               QHash<int, QByteArray> roleNames() const override;


            private:
                bool isIndexValid(const QModelIndex& index) const;

            private:
                DatabaseManager& mDb;    
                std::unique_ptr<std::vector<std::unique_ptr<Domaine>>> mDomaines;

            };

            #endif // DOMAINEMODEL_H




        // domaineModel.cpp




        #include "domainemodel.h"
        using namespace std;

        DomaineModel::DomaineModel(QObject * parent) :
            QAbstractListModel (parent),
            mDb(DatabaseManager::instance()),
            mDomaines(mDb.domaineDao.domaine())
        {

        }

        int DomaineModel::rowCount(const QModelIndex& parent) const
        {
            Q_UNUSED(parent);
            return  mDomaines->size();
        }

        QVariant DomaineModel::data(const QModelIndex& index, int role) const
        {
            if(!isIndexValid(index)) {
                return QVariant();
            }
            const Domaine& domaine = *mDomaines->at(index.row());

            switch (role) {
            case Roles::IdRole:
                return domaine.id();

            case Roles::NameRole:
            case Qt::DisplayRole:
                return domaine.name();

            default:
                return QVariant();
            }
        }

        QHash<int, QByteArray> DomaineModel::roleNames() const
        {
            QHash<int, QByteArray> roles;
            roles[Roles::IdRole] = "id";
            roles[Roles::NameRole] = "name";
            return roles;
        }

        bool DomaineModel::isIndexValid(const QModelIndex& index) const
        {
            if (index.row() < 0
                            || index.row() >= rowCount()
                            || !index.isValid()) {
                return false;
            }
            return true;
        }

        QModelIndex DomaineModel::addDomaine(const Domaine& domaine)
        {
            int rowIndex = rowCount();
            beginInsertRows(QModelIndex(), rowIndex, rowIndex);
            unique_ptr<Domaine> newDomaine(new Domaine(domaine));
            mDb.domaineDao.AddDomaine(*newDomaine);
            mDomaines->push_back(move(newDomaine));
            endInsertRows();
            return index(rowIndex, 0);
        }

        void DomaineModel::addDomaineFromName(const QString& name)
        {
            addDomaine(Domaine(name));
        }



        bool DomaineModel::setData(const QModelIndex& index, const QVariant& value, int role)
        {
            if(!isIndexValid(index)
                    || role != Roles::NameRole) {
                return false;
            }
            Domaine& domaine = *mDomaines->at(index.row());
            domaine.setName(value.toString());
            mDb.domaineDao.updateDomaine(domaine);
            emit dataChanged(index, index);
            return true;
        }

        void DomaineModel::rename(int row, const QString& name)
        {
            setData(index(row), name, Roles::NameRole);
        }

        bool DomaineModel::removeRows(int row, int count, const QModelIndex& parent)
        {
            if (row < 0
                            || row >= rowCount()
                            || count < 0
                            || (row + count) > rowCount()) {
                return false;
            }

            beginRemoveRows(parent, row, row + count -1);
            int countleft = count;
            while (countleft--) {
                const Domaine& domaine = *mDomaines->at(row + countleft);
                mDb.domaineDao.removeDomaine(domaine.id());
            }
            mDomaines->erase(mDomaines->begin() + row,
                                                    mDomaines->begin() + row + count);

            endRemoveRows();
            return true;
        }


    // main.cpp


    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include <QQuickView>

    #include "domainemodel.h"
    #include "typeassocmodel.h"
    #include "associationmodel.h"
    #include "chefmodel.h"
    #include "lieuactionmodel.h"
    #include "partenairemodel.h"
    #include "projetmodel.h"

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

        DomaineModel domaineModel; // my model concerned
        TypeAssocModel typeAssocModel;
        AssociationModel associationModel;
        ChefModel chefModel;
        LieuActionModel lieuActionModel;
        PartenaireModel partenaireModel;
        ProjetModel projetModel;

        QQmlApplicationEngine engine;

        QQmlContext * context = engine.rootContext();
        context->setContextProperty("domaineModel", &domaineModel);
        context->setContextProperty("typeAssocModel", &typeAssocModel);
        context->setContextProperty("associationModel", &associationModel);
        context->setContextProperty("chefModel", &chefModel);
        context->setContextProperty("lieuActionModel", &lieuActionModel);
        context->setContextProperty("partenaireModel", &partenaireModel);
        context->setContextProperty("projetModel", &projetModel);

        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;

        return app.exec();
    }


// MenuFied.qml (part of qml-material)


import QtQuick 2.4
import QtQuick.Layouts 1.1

import Material 0.3
import Material.ListItems 0.1

/*!
   \qmltype MenuField
   \inqmlmodule Material

   \brief A input field similar to a text field but that opens a dropdown menu.
 */
Item {
    id: field

    implicitHeight: hasHelperText ? helperTextLabel.y + helperTextLabel.height + 4 * Units.dp
                                  : underline.y + 8 * Units.dp
    implicitWidth: spinBoxContents.implicitWidth

    activeFocusOnTab: true

    property color accentColor: Theme.accentColor
    property color errorColor: "#F44336"

    property alias model: listView.model

    property string textRole   

    readonly property string selectedText: (listView.currentItem) ? listView.currentItem.text : ""

    property alias selectedIndex: listView.currentIndex
    property int maxVisibleItems: 4

    property alias placeholderText: fieldPlaceholder.text
    property alias helperText: helperTextLabel.text

    property bool floatingLabel: false
    property bool hasError: false
    property bool hasHelperText: helperText.length > 0

    readonly property rect inputRect: Qt.rect(spinBox.x, spinBox.y, spinBox.width, spinBox.height)

    signal itemSelected(int index)

    Ink {
        anchors.fill: parent
        onClicked: {
            listView.positionViewAtIndex(listView.currentIndex, ListView.Center)
            var offset = listView.currentItem.itemLabel.mapToItem(menu, 0, 0)
            menu.open(label, 0, -offset.y)
        }
    }

    Item {
        id: spinBox

        height: 24 * Units.dp
        width: parent.width

        y: {
            if(!floatingLabel)
                return 16 * Units.dp
            if(floatingLabel && !hasHelperText)
                return 40 * Units.dp
            return 28 * Units.dp
        }

        RowLayout {
            id: spinBoxContents

            height: parent.height
            width: parent.width + 5 * Units.dp

            Label {
                id: label

                Layout.fillWidth: true
                Layout.alignment: Qt.AlignVCenter

                text: (listView.currentItem) ? listView.currentItem.text : ""
                style: "subheading"
                elide: Text.ElideRight
            }

            Icon {
                id: dropDownIcon

                Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
                Layout.preferredWidth: 24 * Units.dp
                Layout.preferredHeight: 24 * Units.dp

                name: "navigation/arrow_drop_down"
                size: 24 * Units.dp
            }
        }

        Dropdown {
            id: menu

            anchor: Item.TopLeft

            width: spinBox.width

            //If there are more than max items, show an extra half item so
            // it's clear the user can scroll
            height: Math.min(maxVisibleItems*48 * Units.dp + 24 * Units.dp, listView.contentHeight)

            ListView {
                id: listView

                width: menu.width
                height: count > 0 ? menu.height : 0

                interactive: true

                delegate: Standard {
                    id: delegateItem

                    text: textRole ? model[textRole] : modelData

                    onClicked: {
                        itemSelected(index)
                        listView.currentIndex = index
                        menu.close()
                    }
                }
            }

            Scrollbar {
                flickableItem: listView
            }
        }
    }

    Label {
        id: fieldPlaceholder

        text: field.placeholderText
        visible: floatingLabel

        font.pixelSize: 12 * Units.dp

        anchors.bottom: spinBox.top
        anchors.bottomMargin: 8 * Units.dp

        color: Theme.light.hintColor
    }

    Rectangle {
        id: underline

        color: field.hasError ? field.errorColor : field.activeFocus ? field.accentColor : Theme.light.hintColor

        height: field.activeFocus ? 2 * Units.dp : 1 * Units.dp

        anchors {
            left: parent.left
            right: parent.right
            top: spinBox.bottom
            topMargin: 8 * Units.dp
        }

        Behavior on height {
            NumberAnimation { duration: 200 }
        }

        Behavior on color {
            ColorAnimation { duration: 200 }
        }
    }

    Label {
        id: helperTextLabel

        anchors {
            left: parent.left
            right: parent.right
            top: underline.top
            topMargin: 4 * Units.dp
        }

        visible: hasHelperText
        font.pixelSize: 12 * Units.dp
        color: field.hasError ? field.errorColor : Qt.darker(Theme.light.hintColor)

        Behavior on color {
            ColorAnimation { duration: 200 }
        }
    }
}

// AjouterAssociation.qml

import QtQuick 2.4
import QtQuick.Layouts 1.1
import Material 0.2
import Material.ListItems 0.1 as ListItem
import Material.Extras 0.1


Item {    
       property int domaineId
//    property int typeId


    View {
        anchors.fill: parent
        anchors.margins: dp(32)
        width: dp(350)
        height: column.implicitHeight + dp(32)

        elevation: 1
        radius: dp(2)

        ColumnLayout {
            id: column

            anchors {
                fill: parent
                topMargin: dp(16)
                bottomMargin: dp(16)
            }

            Label {
                id: titleLabel

                anchors {
                    fill: parent
                    leftMargin:  dp(100)
                }

                style: "title"
                text: "Ajout Association"
            }

            Item {
                Layout.fillWidth: true
                Layout.preferredHeight: dp(8)
            }

            ListItem.Standard {
                action: Icon {
                    anchors.centerIn: parent
                    name: "action/settings"
                }

                Icon {
                    anchors.centerIn: parent
                    name: "action/account_circle"
                }

                content: RowLayout {
                    anchors.centerIn: parent
                    width: parent.width

                    TextField {
                        id: code
                        Layout.alignment: Qt.AlignVCenter
                        Layout.preferredWidth: 0.4 * parent.width

                        placeholderText: "Code"
                    }

                    TextField {
                        id:name
                        Layout.alignment: Qt.AlignVCenter
                        Layout.preferredWidth: 0.4 * parent.width

                        placeholderText: "Nom"
                    }
                }
            }

            ListItem.Standard {
                action: Icon {
                    anchors.centerIn: parent
                    name: "action/account_circle"
                }

                content: RowLayout {
                    anchors.centerIn: parent
                    width: parent.width

                    TextField {
                        id: adresse
                        Layout.alignment: Qt.AlignVCenter
                        Layout.preferredWidth: 0.4 * parent.width

                        placeholderText: "Adresse"
                    }

                    TextField {
                        id:telephone
                        Layout.alignment: Qt.AlignVCenter
                        Layout.preferredWidth: 0.4 * parent.width

                        placeholderText: "Telephone"
                    }
                }
            }

            ListItem.Standard {
                action: Icon {
                    anchors.centerIn: parent
                    name: "communication/email"
                }

                Icon {
                    anchors.centerIn: parent
                    name: ""
                }

                content: RowLayout {
                    anchors.centerIn: parent
                    width: parent.width

                    TextField {
                        id:email
                        Layout.alignment: Qt.AlignVCenter
                        Layout.preferredWidth: 0.4 * parent.width

                        placeholderText: "Email"
                    }

                    TextField {
                        id: codePostal
                        Layout.alignment: Qt.AlignVCenter
                        Layout.preferredWidth: 0.4 * parent.width

                        placeholderText: "Code Postal"
                    }
                }
            }

            ListItem.Standard {
                content: RowLayout {
                    anchors.centerIn: parent
                    width: parent.width

                    Text {
                        id: textDomaine
                        text: qsTr("Domaine")
                    }

                    MenuField {
                        id: domaine
                        Layout.alignment: Qt.AlignVCenter
                        Layout.preferredWidth: 0.3 * parent.width
                        model: domaineModel
                        textRole: "name"

                        //domaineId:
                    }



                    Text {
                        id: textType
                        text: qsTr("Type Association")
                    }

                    MenuField {
                        id: typeAssoc
                        Layout.alignment: Qt.AlignVCenter
                        Layout.preferredWidth: 0.3 * parent.width
                        model: typeAssocModel
                        textRole: "libelle"
                        selectedText: "libelle"

                        typeId: typeAssocModel.typeForLibelle(selectedText)

                    }
                }
            }

            Item {
                Layout.fillWidth: true
                Layout.preferredHeight: dp(8)
            }

            RowLayout {
                Layout.alignment: Qt.AlignRight
                spacing: dp(8)

                anchors {
                    right: parent.right
                    margins: dp(16)
                }

                Button {
                    text: "Annuler"
                    textColor: Theme.primaryColor
                    onClicked: {
                        code.text = ""
                        name.text = ""
                        adresse.text = ""
                        telephone.text = ""
                        email.text = ""
                        codePostal.text = ""
                    }
                }

                Button {
                    text: "Valider"
                    textColor: Theme.primaryColor
                    onClicked: associationModel.add(code.text, name.text, adresse.text, telephone.text, email.text, codePostal.text, 1, 1)
                }
            }
        }
    }
}

0 个答案:

没有答案