【零基础学QT】【049】Model-View-Delegate界面设计模式

Model-View-Delegate是Qt中复合控件的一种设计模式
如ListView,TableView,ComboBox等控件,都会用到这种设计模式

设计原理

【Model-View-Delegate】翻译成中文就是【模型-视图-代理】,它的思想是这样的:

  • 用一个model对线来存储数据源,一般是一个数组或List
  • View只绘制控件的基础部分,比如ComboBox,它只负责文本标签和下拉箭头的绘制
  • 复合控件的子元素交给delegate去绘制,delegate定义了如何将model中的单个元素绘制成一个子项视图

示例代码

Model-View-Delegate界面设计模式既适用于Qt Widget,也适用于Qt Quick,这里我们以Qt Quick为例


	//main.qml

	import QtQuick 2.12
	import QtQuick.Controls 2.12
	
	ComboBox {
	    id: combo
	    width: 300
	    height: 50
	
	    //数据源
	    model: [{
	            "name": "Programmer A",
	            "age": 25
	        }, {
	            "name": "Programmer B",
	            "age": 26
	        }, {
	            "name": "Programmer C",
	            "age": 27
	        }]
	
	    //选中项
	    currentIndex: -1
	
	    //定义某一下拉项的视图
	    delegate: ItemDelegate {
	        width: combo.width
	        contentItem: Text {
	            text: modelData.name + "  " + modelData.age //modelData属性对应某一下拉项的数据
	            color: "darkgreen"
	            font: combo.font
	            verticalAlignment: Text.AlignVCenter
	            elide: Text.ElideRight
	        }
	        highlighted: combo.highlightedIndex == index //highlighted表示鼠标正悬浮在当前项上
	    }
	
	    //定义主文本标签的视图
	    contentItem: Text {
	        leftPadding: 10
	        rightPadding: indicator.width + 10
	        text: combo.currentIndex < 0 ? "please select your option" : model[combo.currentIndex].name
	        font: combo.font
	        color: combo.pressed ? "green" : "darkgreen"
	        horizontalAlignment: Text.AlignLeft
	        verticalAlignment: Text.AlignVCenter
	        elide: Text.ElideRight
	    }
	
	    //定义主文本标签后的下拉箭头
	    indicator: Canvas {
	        x: combo.width - combo.rightPadding - width
	        y: combo.height / 2 - height / 2
	        width: 12
	        height: 8
	        contextType: "2d"
	
	        onPaint: {
	            context.reset()
	            context.moveTo(0, 0)
	            context.lineTo(width, 0)
	            context.lineTo(width / 2, height)
	            context.closePath()
	            context.fillStyle = combo.pressed ? "green" : "darkgreen"
	            context.fill()
	        }
	
	        Connections {
	            target: combo
	            onPressedChanged: indicator.requestPaint()
	        }
	    }
	
	    //定义主文本标签背景边框
	    background: Rectangle {
	        border.color: combo.pressed ? "green" : "darkgreen"
	        border.width: 1
	        radius: 2
	    }
	
	    //定义下拉弹窗样式
	    popup: Popup {
	        y: combo.height - 1
	        width: combo.width
	        height: listview.contentHeight
	        padding: 1
	
	        contentItem: ListView {
	            id: listview
	            model: combo.delegateModel
	            currentIndex: combo.highlightedIndex
	            clip: true
	
	            ScrollIndicator.vertical: ScrollIndicator {
	            }
	        }
	
	        background: Rectangle {
	            border.color: "darkgreen"
	            radius: 2
	        }
	    }
	}



	//main.cpp

	#include <QGuiApplication>
	#include <QQuickView>
	
	int main(int argc, char *argv[]) {
	    QGuiApplication app(argc, argv);
	
	    QQuickView view;
	    view.setSource(QUrl("qrc:///main.qml"));
	    view.show();
	
	    return app.exec();
	}
	
发布了442 篇原创文章 · 获赞 45 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/u013718730/article/details/104203469