QtQuick 如何实现瀑布流



  • QtQuick 如何实现瀑布流?

    如下图

    0_1477491918319_upload-343647dc-5add-46c1-94c8-93f89ae87141

    每个元素都是等宽的(每行8个),但是高度不一样,在视图宽度调整后(每行6个),就会重新布局,该怎么实现呢?



  • 可以尝试用qml的流布局Flow



  • 随手写一个呗

    import QtQuick 2.0
    
    Item {
    	width: 800
    	height: 600
    
    	Item {
    		id: flow
    		anchors.top: parent.top
    		anchors.bottom: parent.bottom
    		anchors.horizontalCenter: parent.horizontalCenter
    		width: columns * (cardWidth+spacing) - spacing
    		anchors.margins: 8
    
    
    		property int spacing: 8
    		property int cardWidth: 80
    		property int animeDuration: 120
    		property int columns: (parent.width+spacing)/(cardWidth+spacing)
    		property int length
    		property var cards: []
    		property var bottoms: []
    
    		function update(item) {
    			var upCard = bottoms[0]
    			var column = 0
    			for (var i = 1;i<columns;i++) {
    				if (bottoms[i].bottomY<upCard.bottomY) {
    					upCard = bottoms[i]
    					column = i
    				}
    			}
    
    			item.upCard = upCard
    			upCard.downCard = item
    			item.column = column
    			bottoms[column] = item
    		}
    
    		function push(item) {
    			cards.push(item)
    			update(item)
    			length = cards.length
    		}
    
    		function remove(idx) {
    			var item = cards[idx]
    			cards = cards.slice(0, idx).concat(cards.slice(idx+1))
    			item.upCard.downCard = item.downCard
    			item.downCard.upCard = item.upCard
    			if (item === bottoms[item.column])
    				bottoms[item.column] = item.upCard
    			item.opacity = 0
    			length = cards.length
    		}
    
    		Item {
    			id: dummy
    			property int bottomY: y+height
    			property Item upCard: dummy
    			property Item downCard: dummy
    			x: 0
    			y: 0
    			width: 0
    			height: 0
    		}
    
    		Item {
    			id: bottomy
    			property int bottomY: y+height
    			property Item upCard: dummy
    			property Item downCard: dummy
    			x: parent.width/2
    			y: parent.height
    			width: 0
    			height: 0
    		}
    
    		Component {
    			id: card
    
    			Rectangle {
    				property int bottomY: y+height
    				property Item upCard: bottomy
    				property Item downCard: bottomy
    				property int column: flow.columns/2
    				opacity: 0
    				x: (width + flow.spacing)*column
    				y: upCard.y + upCard.height + flow.spacing
    				width: flow.cardWidth
    				height: 40 + Math.random()*80
    				color: Qt.hsla(Math.random(), .7, .5, 1.)
    				Behavior on x {
    					NumberAnimation {
    						duration: flow.animeDuration
    					}
    				}
    
    				Behavior on y {
    					NumberAnimation {
    						duration: flow.animeDuration
    					}
    				}
    
    				Behavior on opacity {
    					NumberAnimation {
    						duration: flow.animeDuration
    					}
    				}
    
    				onOpacityChanged: {
    					if (opacity <=0)
    						destroy()
    				}
    
    				Component.onCompleted:
    					opacity = 1
    			}
    		}
    
    		onColumnsChanged: {
    			bottoms = []
    			for (var i=0;i<columns;i++)
    				bottoms.push(dummy)
    			for (var i=0;i<length;i++)
    				update(cards[i])
    		}
    	}
    
    	Timer {
    		repeat: true
    		interval: flow.animeDuration * 2
    		running: true
    		triggeredOnStart: true
    
    		onTriggered: {
    			var r = Math.random()
    			if (r>flow.length/50) {
    				info.text = "Append to flow at %1".arg(flow.length)
    				flow.push(card.createObject(flow))
    			}
    			else {
    				r = Math.random()
    				r = parseInt(r*flow.length)
    				info.text = "Remove from flow at %1".arg(r)
    				flow.remove(r)
    			}
    		}
    	}
    
    	Text {
    		id: info
    		x: 8
    		y: parent.height - font.pixelSize - 8
    	}
    }
    
    

    这里没考虑动画引发的更新问题,自己修一下啦



  • 第一张图23333

    0_1477564128319_Screenshot_2016-10-27-18-04-39.png



  • @MidoriYakumo 你们也是厉害哦。哇哇哇,第一张图。要解开罩子,还需要会玩魔方???真会玩。



  • @MidoriYakumo 非常谢谢,最近写太多 Java 了,QML 开始生疏了。



  • @qyvlik 最新写太多C++,老板微软出身,全是STDMETHOD啥的,写javascript都是一派C的风格,真想让他用Go写。。。



  • @MidoriYakumoQtQuick 如何实现瀑布流 中说:

    c 风格的 js,写得也是够呛。



  • @qyvlikQtQuick 如何实现瀑布流 中说:

    @MidoriYakumoQtQuick 如何实现瀑布流 中说:

    c 风格的 js,写得也是够呛。

    非常赞同。我会尽量将带函数的代码封装到单一的QML文件中。



走马观花

最近的回复

  • 诶 没有Linux吗??

    read more
  • 萌梦 男孩,女孩,和蛋

    menghome.png

    read more
  • 设计模式-工厂模式

    使用qt/qml来演示设计模式效果,便于学习理解

    1)定义创建对象的接口,封装对象的创建
    2)使具体化类的工作延迟到工厂子类中

    bg.png
    image.png

    1. 工厂类

    createProduct使用了参数来选择要创建哪个产品

    #ifndef FACTORY_H #define FACTORY_H #include <QObject> class Product; class QString; class Factory: public QObject { Q_OBJECT public: virtual ~Factory() = 0; virtual Product* createProduct(QString type) = 0; protected: Factory(); }; class ConcreteFactory: public Factory { Q_OBJECT public: ~ConcreteFactory(); ConcreteFactory(); public slots: Product* createProduct(QString type); }; #endif // FACTORY_H #include "factory.h" #include "product.h" #include <QtQml/qqml.h> Factory::~Factory() { } Factory::Factory() { qmlRegisterType<Product>("Product", 1, 0, "Product"); } ConcreteFactory::~ConcreteFactory() { } ConcreteFactory::ConcreteFactory() { } Product *ConcreteFactory::createProduct(QString type) { if(type == "boy") return static_cast<Product *>(new ConcreteProduct1()); else if(type == "girl") return static_cast<Product *>(new ConcreteProduct2()); return static_cast<Product *>(new ConcreteProduct1()); } 2 产品类

    一个产品是萌梦男,一个产品是萌梦女

    #ifndef PRODUCT_H #define PRODUCT_H #include <QObject> class Product: public QObject { Q_OBJECT public: virtual ~Product() = 0; Q_PROPERTY(QString icon READ icon NOTIFY iconChanged) QString m_icon; QString icon() const { return m_icon; } signals: void iconChanged(QString icon); protected: Product(); signals: public slots: }; class ConcreteProduct1: public Product { Q_OBJECT public: ~ConcreteProduct1(); ConcreteProduct1(); }; class ConcreteProduct2: public Product { Q_OBJECT public: ~ConcreteProduct2(); ConcreteProduct2(); }; #endif // PRODUCT_H #include "product.h" Product::~Product() { } Product::Product() { } ConcreteProduct1::~ConcreteProduct1() { } ConcreteProduct1::ConcreteProduct1() { m_icon = "qrc:/images/boy.png"; } ConcreteProduct2::~ConcreteProduct2() { } ConcreteProduct2::ConcreteProduct2() { m_icon = "qrc:/images/girl.png"; } 3. main.qml

    使用timer,canvas,listview等实现一个自动化生产的动画效果

    源代码

    Fork me on Gitee

    read more
  • blender建模 章鱼
    捕获2.PNG 😵

    read more

关注我们

微博
QQ群