QML PathView 實現 public QAbstractItemModel

QML 實現 PathView 主要分下面幾步

 

1 注意幾個關鍵函數的實現

    //向View 傳輸當前索引
    int GetCurrentIndex(){return currentIndex;}
    void SetCurrentIndex(const int curIndex) {currentIndex = curIndex; emit CurrentIndexChanged();}

 2 // 必須要實現的虛函數
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    QHash<int, QByteArray> roleNames() const;

 

 //插入element 時

   void QMyModel::InsertElement()
{
    QMyElement element(nullptr);
    QString key = QString::number(qrand() %10000);
    element.donorName = "Test element ";
    element.IPAddress = "0.0.0.0: Test " + key;
    elementMap.insert(key,element);
    int i = GetMapKeyIndex(elementMap, key);
    beginInsertRows(QModelIndex(), i, i);
    endInsertRows();

    SetCurrentIndex(i);

}

更新element 時   dataChanged(modeStart, modeEnd);

void QMyModel::ResetData(int i)
{
    QModelIndex modeStart = createIndex(i, -1);
    QModelIndex modeEnd = createIndex(i, -1);
    dataChanged(modeStart, modeEnd);
    SetCurrentIndex(i);
    
}

3 注意 main.qml 中

Component {

id:delegate 

 對應 PathView 中 delegate 屬性  

    PathView {
        id: pathView;
        anchors.fill: parent
        currentIndex: MyModel.GetCurrentIndex;

        x: 500
        y: 0
        width: 1000;
        height: 900;
        model: MyModel
        delegate: delegate

 

4 注意 main函數中 MyModel 和 QMyModel 對應

    QMyModel model;
    gMyModel = &model;    

   QtQuick2ApplicationViewer viewer;
    QQmlContext *ctxt = viewer.rootContext();
    ctxt->setContextProperty("MyModel", &model);

 

Qmymodel.h 文件

定義QMyModel 類

#ifndef QMYMODEL_H
#define QMYMODEL_H



#include <QAbstractListModel>
#include <QColor>
#include "QMyElement.h"
#include <QMap>

int GetMapKeyIndex(QMap<QString, QMyElement> &map, QString key);

class QMyModel : public QAbstractListModel
{
	Q_OBJECT
	Q_PROPERTY(int GetCurrentIndex READ GetCurrentIndex WRITE SetCurrentIndex  NOTIFY CurrentIndexChanged)

public:

	enum LineInfo_Roles{
		DeviceID =Qt::UserRole + 1,
		DonorID,
		DonorName,
		OperatorID,
		OperatorName,
		Index,
		IPAddress,
		Port
	};

	QMyModel(QObject *parent = 0);
	~QMyModel();

	//向View 傳輸當前索引
	int GetCurrentIndex(){return currentIndex;}
	void SetCurrentIndex(const int curIndex) {currentIndex = curIndex; emit CurrentIndexChanged();}

	// 必須要實現的虛函數
	int rowCount(const QModelIndex &parent = QModelIndex()) const override;
	QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
	QHash<int, QByteArray> roleNames() const;


private:
	QVector<QString> m_chatItem;
	QString m_Name;
	QColor m_color;
	int currentIndex;

public:
	//ThriftUdpServer tUdpServer;

public:
	QList<QMyElement> elementList;

	QMap<QString, QMyElement> elementMap;
	

signals:
	void ResetDataSignal(int i);
	void InsertElementSignal(int i);
	void CurrentIndexChanged();

	public slots:
		void ResetData(int i);
		void InsertElement();
		void InsertElement(int i);
		void RemoveElement(int i);
		

};

#endif // QMYMODEL_H

實現QMyModel 類 Qmymodel.cpp

#include "qmymodel.h"

QMyModel::QMyModel(QObject *parent)
	: QAbstractListModel(parent)
{
	//tUdpServer.Init();
	//tUdpServer.RunServer();
	connect(this, SIGNAL(ResetDataSignal(int)), this, SLOT(ResetData(int)));
	connect(this, SIGNAL(InsertElementSignal(int)), this, SLOT(InsertElement(int)));
}

QMyModel::~QMyModel()
{

}

void QMyModel::setName(const QString &name)
{

}

void QMyModel::setColor(const QColor &color)
{

}

int QMyModel::rowCount(const QModelIndex &parent /*= QModelIndex()*/) const 
{
	return elementMap.size();
}

QHash<int, QByteArray> QMyModel::roleNames() const
{
	QHash<int, QByteArray> roles;
	roles[DeviceID] = "DeviceID";
	roles[DonorID] = "DonorID";
	roles[DonorName]= "DonorName";
	roles[OperatorID]= "OperatorID";
	roles[OperatorName]= "OperatorName";
	roles[Index]= "Index";
	roles[IPAddress]= "IPAddress";
	roles[Port]= "Port";
	return roles;
}

QVariant QMyModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole*/) const 
{
	//
	QList<QString> keysList =  elementMap.keys();
	if (keysList.isEmpty())
	{
		return QVariant();
	}
	QString key = keysList[index.row()];
	QMyElement element = elementMap[key];

	switch(role)
	{
	case DeviceID:
		return element.deviceID;
	case DonorID:
		return element.donorID;
	case DonorName:
		return element.donorName;
	case OperatorID:
		return element.operatorID;
	case OperatorName:
		return element.operatorName;
	case Index:
		return element.index;
	case IPAddress:
		return element.IPAddress;
	case Port:
		return element.port;

	}

	return QVariant();

}



void QMyModel::ResetData(int i)
{
	QModelIndex modeStart = createIndex(i, -1);
	QModelIndex modeEnd = createIndex(i, -1);
	dataChanged(modeStart, modeEnd);
	SetCurrentIndex(i);
	
}

int GetMapKeyIndex(QMap<QString, QMyElement> &map, QString key)
{
	QList<QString> keylist = map.keys();
	int i = 0;
	int keyIndex = -1;
	while(i < keylist.size())
	{
		if (key.compare(keylist[i]) == 0)
		{
			keyIndex = i;
			break;
		}
		i++;
	}
	return keyIndex;
}

/// Test methon
void QMyModel::InsertElement()
{
	QMyElement element(nullptr);
	QString key = QString::number(qrand() %10000);
	element.donorName = "Test element ";
	element.IPAddress = "0.0.0.0: Test " + key;
	elementMap.insert(key,element);
	int i = GetMapKeyIndex(elementMap, key);
	beginInsertRows(QModelIndex(), i, i);
	endInsertRows();
	SetCurrentIndex(i);

	printf("currentIndex %d \n", i);

}

void QMyModel::InsertElement(int i)
{
	beginInsertRows(QModelIndex(), i, i);
	endInsertRows();
	SetCurrentIndex(i);
}

void QMyModel::RemoveElement(int i)
{
	if (i < 0)
	{
		return;
	}
	beginRemoveRows(QModelIndex(), i, i);
	endRemoveRows();
	
	QList<QString> keysList =  elementMap.keys();
	if (keysList.isEmpty())
	{
		return ;
	}
	QString key = keysList[i];
	QMyElement element = elementMap[key];
	QMap<QString, QMyElement>::Iterator it = elementMap.find(key);
	elementMap.erase(it);
	SetCurrentIndex(i-1);

}



定義PathView 注意 model:MyModel

main.Qml

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.2



Rectangle {

	

	id : root
    width: 1600
    height: 900
    property int fontSize: 18;
    property int rW: 600;
    property int rH: 450;
    property int sX: 20;
    property int sY: 20;

    Keys.onEscapePressed: {
            Qt.quit();
    }
    //color: "lightskyblue"
    gradient: Gradient {
        GradientStop { position: 0.0; color: Qt.rgba(Math.random() , Math.random(), Math.random(), 1);}
        GradientStop { position: 0.5; color: "#0000DD";}
        GradientStop { position: 1.0; color: Qt.rgba(Math.random() , Math.random(), Math.random(), 1); }
    }



    Component {
        id: delegate
        Rectangle{
            id: wrapper
            //id : rect
            width: rW
            height: rH
            //color: Qt.rgba(Math.random() , Math.random(), Math.random(), 1);
            gradient: Gradient {
                GradientStop { position: 0.0; color: Qt.rgba(Math.random() , Math.random(), Math.random(), 1);}
                GradientStop { position: 0.5; color: "#0000DD";}
                GradientStop { position: 1.0; color: Qt.rgba(Math.random() , Math.random(), Math.random(), 1); }
            }
            border.width: 5
            border.color: wrapper.PathView.isCurrentItem ? "red" : "lightgray";

            z: PathView.zOrder;
            opacity: PathView.itemAlpha;
            scale: PathView.itemScale;

            MouseArea {
                 anchors.fill: parent
                 onClicked: {
                    pathView.currentIndex = index;
                    console.log("mouse clicked ", pathView.currentIndex);
                 }

            }
            //左側
            Column{
                spacing: rH *0.03;
                x: rW * 0.05;
                y: rH *0.05;
                //左側第一行
                Row {

                    spacing: rW * 0.03
                    Rectangle{
                        width: rW * 0.15;
                        height: rH * 0.1;
                        color: "#3A87F1"
                        radius: 5;
                        Text{
                            anchors.horizontalCenter: parent.horizontalCenter;
                            anchors.verticalCenter: parent.verticalCenter;
                            text: "PROTOCOL\nText";
                            font.pixelSize: fontSize;
                            color: "yellow"
                            font.bold: true
                        }
                    }

                    Rectangle{
                        width: rW * 0.20;
                        height: rH * 0.1;
                        color: "#3A87F1"
                        radius: 5;
                        Text{
                            anchors.horizontalCenter: parent.horizontalCenter;
                            anchors.verticalCenter: parent.verticalCenter;
                            text: "PLASMA\nText";
                            font.pixelSize: fontSize;
                            color: "yellow"
                            font.bold: true
                        }
                    }

                    Rectangle{
                        width: rW * 0.15;
                        height: rH * 0.1;
                        color: "#3A87F1"
                        radius: 5;
                        Text{
                            anchors.horizontalCenter: parent.horizontalCenter;
                            anchors.verticalCenter: parent.verticalCenter;
                            text: "CYCLE\nText";
                            font.pixelSize: fontSize;
                            color: "yellow"
                            font.bold: true
                        }
                    }

                }
                //左側第二行
                Rectangle{
                    width: rW *0.56;
                    height: rH *0.3;
                    color: "#EEEEEE"
                    radius: 5;
                    Text{
                        //anchors.horizontalCenter: parent.horizontalCenter;
                        x: rW * 0.05;
                        anchors.verticalCenter: parent.verticalCenter;
                        text: DeviceID + "\n\n" + IPAddress + " : " + Port;
                        font.pixelSize: fontSize + 6;
                        color: "blue"
                        font.bold: true
                    }
                }
                //左側第三行
                Rectangle{
                    width: rW *0.56;
                    height: rH *0.15;
                    color: "#9ABCF3"
                    radius: 5;
                    Column{
                        x: rW *0.01;
                        y: rH *0.01;
                        //spacing: rH*0.02;
                        Rectangle{

                            width: rW *0.54
                            height: rH *0.065
                            border.width: rW *0.001;
                            border.color: "#ffffff"
                            color : "#9ABCF3"
                            Text{
                                //anchors.horizontalCenter: parent.horizontalCenter;

                                //anchors.verticalCenter: parent.verticalCenter;
                                x: rW *0.01;
                                y: rH *0.01;
                                text: DonorName + " " + DonorID;
                                font.pixelSize: fontSize;
                                color: "yellow"
                                font.bold: true
                            }
                        }


                        RowLayout {
                            spacing: 0
                            Rectangle{

                                width: rW *0.27
                                height: rH *0.065
                                border.width: rW *0.001;
                                border.color: "#ffffff"
                                color : "#9ABCF3"
                                Text{
                                    //anchors.horizontalCenter: parent.horizontalCenter;

                                    //anchors.verticalCenter: parent.verticalCenter;
                                    x: rW *0.01;
                                    y: rH *0.01;
                                    text: "PVB(ml)";
                                    font.pixelSize: fontSize;
                                    color: "yellow"
                                    font.bold: true
                                }
                            }


                            Rectangle{

                                width: rW *0.27
                                height: rH *0.065
                                border.width: rW *0.001;
                                border.color: "#ffffff"
                                color : "#9ABCF3"
                                Text{
                                    //anchors.horizontalCenter: parent.horizontalCenter;

                                    //anchors.verticalCenter: parent.verticalCenter;
                                    x: rW *0.01;
                                    y: rH *0.01;
                                    text: "SCV(ml)";
                                    font.pixelSize: fontSize;
                                    color: "yellow"
                                    font.bold: true
                                }
                            }
                        }


                    }


                }
                //左側第四行
                Rectangle{
                    width: rW *0.56;
                    height: rH *0.25;
                    color: "#9ABCF3"
                    radius: 5;
                    //左側四行 1列
                    Column{
                        x: rW *0.01;
                        y: rH *0.01;
                        //spacing: rH*0.02;
                        Rectangle{

                            width: rW *0.27
                            height: rH *0.0725
                            border.width: rW *0.001;
                            border.color: "#ffffff"
                            color : "#9ABCF3"
                            Text{
                                anchors.horizontalCenter: parent.horizontalCenter;

                                //anchors.verticalCenter: parent.verticalCenter;
                                x: rW *0.01;
                                y: rH *0.01;
                                text: "PUMP";
                                font.pixelSize: fontSize+6;
                                color: "yellow"
                                font.bold: true
                            }
                        }


                        RowLayout {
                            spacing: 0
                            Rectangle{

                                width: rW *0.135
                                height: rH *0.0725
                                border.width: rW *0.001;
                                border.color: "#ffffff"
                                color : "#9ABCF3"
                                Text{
                                    //anchors.horizontalCenter: parent.horizontalCenter;

                                    //anchors.verticalCenter: parent.verticalCenter;
                                    x: rW *0.01;
                                    y: rH *0.01;
                                    text: "Draw";
                                    font.pixelSize: fontSize;
                                    color: "yellow"
                                    font.bold: true
                                }
                            }

                            Rectangle{

                                width: rW *0.135
                                height: rH *0.0725
                                border.width: rW *0.001;
                                border.color: "#ffffff"
                                color : "#9ABCF3"
                                Text{
                                    //anchors.horizontalCenter: parent.horizontalCenter;

                                    //anchors.verticalCenter: parent.verticalCenter;
                                    x: rW *0.01;
                                    y: rH *0.01;
                                    text: "Return";
                                    font.pixelSize: fontSize;
                                    color: "yellow"
                                    font.bold: true
                                }
                            }
                        }
                        RowLayout {
                            spacing: 0
                            Rectangle{

                                width: rW *0.135
                                height: rH *0.0725
                                border.width: rW *0.001;
                                border.color: "#ffffff"
                                color : "#9ABCF3"
                                Text{
                                    //anchors.horizontalCenter: parent.horizontalCenter;

                                    //anchors.verticalCenter: parent.verticalCenter;
                                    x: rW *0.01;
                                    y: rH *0.01;
                                    text: "Value";
                                    font.pixelSize: fontSize;
                                    color: "yellow"
                                    font.bold: true
                                }
                            }

                            Rectangle{

                                width: rW *0.135
                                height: rH *0.0725
                                border.width: rW *0.001;
                                border.color: "#ffffff"
                                color : "#9ABCF3"
                                Text{
                                    //anchors.horizontalCenter: parent.horizontalCenter;

                                    //anchors.verticalCenter: parent.verticalCenter;
                                    x: rW *0.01;
                                    y: rH *0.01;
                                    text: "Value";
                                    font.pixelSize: fontSize;
                                    color: "yellow"
                                    font.bold: true
                                }
                            }
                        }



                    }
                    //左側四行 2列
                    Column{
                        x: rW *0.28;
                        y: rH *0.01;
                        RowLayout {
                            spacing: 0
                            Rectangle{

                                width: rW *0.135
                                height: rH *0.15
                                border.width: rW *0.001;
                                border.color: "#ffffff"
                                color : "#9ABCF3"
                                Text{
                                    anchors.horizontalCenter: parent.horizontalCenter;

                                    anchors.verticalCenter: parent.verticalCenter;
                                    x: rW *0.01;
                                    y: rH *0.01;
                                    text: "Value";
                                    font.pixelSize: fontSize;
                                    color: "yellow"
                                    font.bold: true
                                }
                            }

                            Rectangle{

                                width: rW *0.135
                                height: rH *0.15
                                border.width: rW *0.001;
                                border.color: "#ffffff"
                                color : "#9ABCF3"
                                Text{
                                    anchors.horizontalCenter: parent.horizontalCenter;

                                    anchors.verticalCenter: parent.verticalCenter;

                                    text: "Value";
                                    font.pixelSize: fontSize;
                                    color: "yellow"
                                    font.bold: true
                                }
                            }
                        }

                        RowLayout {
                            spacing: 0
                            Rectangle{

                                width: rW *0.135
                                height: rH *0.0725
                                border.width: rW *0.001;
                                border.color: "#ffffff"
                                color : "#9ABCF3"
                                Text{
                                    anchors.horizontalCenter: parent.horizontalCenter;

                                    anchors.verticalCenter: parent.verticalCenter;

                                    text: "Value";
                                    font.pixelSize: fontSize;
                                    color: "yellow"
                                    font.bold: true
                                }
                            }

                            Rectangle{

                                width: rW *0.135
                                height: rH *0.0725
                                border.width: rW *0.001;
                                border.color: "#ffffff"
                                color : "#9ABCF3"
                                Text{
                                    anchors.horizontalCenter: parent.horizontalCenter;

                                    anchors.verticalCenter: parent.verticalCenter;

                                    text: "Value";
                                    font.pixelSize: fontSize;
                                    color: "yellow"
                                    font.bold: true
                                }
                            }
                        }

                    }
                }
            }
            //右側
            Column{
                spacing: rH *0.03;
                x: rW * 0.65;
                y: rH *0.05;

                Rectangle{
                    width: rW * 0.30;
                    height: rH * 0.43;
                    color: "#EEEEEE"
                    radius: 5;
                    Text{
                        anchors.horizontalCenter: parent.horizontalCenter;
                        anchors.verticalCenter: parent.verticalCenter;
                        text: "PLASMA\nText";
                        font.pixelSize: fontSize;
                        color: "blue"
                        font.bold: true
                    }
                }
                Rectangle{
                    width: rW * 0.30;
                    height: rH * 0.43;
                    color: "#EEEEEE"
                    radius: 5;
                    Text{
                        anchors.horizontalCenter: parent.horizontalCenter;
                        anchors.verticalCenter: parent.verticalCenter;
                        text: "PLASMA\nText";
                        font.pixelSize: fontSize;
                        color: "blue"
                        font.bold: true
                    }
                }
            }
        }
    }

    PathView {
        id: pathView;
        anchors.fill: parent
        currentIndex: MyModel.GetCurrentIndex;

        x: 500
        y: 0
        width: 1000;
        height: 900;
        model: MyModel
        delegate: delegate
        preferredHighlightBegin: 0.49;
        preferredHighlightEnd: 0.51;
		focus: true;
        Keys.onLeftPressed: decrementCurrentIndex();
        Keys.onRightPressed: incrementCurrentIndex();

		path: Path{
    
            startX: pathView.width/2;
			startY: 30;
            PathAttribute { name: "zOrder"; value: 0 }
            PathAttribute { name: "itemAlpha"; value: 0.5 }
            PathAttribute { name: "itemScale"; value: 0.3 }
            PathArc {
                relativeX: 0;
                y: pathView.height - rH/1.5;
                radiusX: pathView.width/4;
                radiusY: pathView.width/4;
				useLargeArc:true
			}
            PathAttribute { name: "zOrder"; value: 50 }
            PathAttribute { name: "itemAlpha"; value: 1.0 }
            PathAttribute { name: "itemScale"; value: 1.0 }
            PathArc {
                x: pathView.width/2;
                y: 0
                radiusX: pathView.width/4;
                radiusY: pathView.width/4;
				useLargeArc:true
            }
            PathAttribute { name: "zOrder"; value: 0 }
            PathAttribute { name: "itemAlpha"; value: 0.5 }
            PathAttribute { name: "itemScale"; value: 0.3 }

		}
    }


}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章