Qt Quick使用listview实现treeview的方法

来源:互联网 发布:怎么打开telnet端口23 编辑:程序博客网 时间:2024/06/05 21:49
  • 背景

    由于在项目中需要实现treeview中的单元实现上下拖动功能,Qt Quick自身的treeview虽然能够实现树形结构功能,但却无法实现树形节点的拖动功能。于是考虑用listview来实现treeview的功能,在网上提的比较多的是listview+repeat方法,手动实践过,可以实现预期效果,但这个方法最大的缺点是如果有三个树形节点单元,在鼠标滚动时,listview的滚动条上的滑块定位不准而且时常的跳上跳下,已闭合的树形节点也会在滚动时被自动打开,数据量几千条时有时listview中的数据会跑飞,就是没有了。调试过发现滚动鼠标滚轮时会自动执行mousearea的doubleclicked事件,所以感觉这个方法不靠谱。

  • 方法思路

    于是考虑自己用listview+逻辑组合的方式实现treeview,即在model里面做好树形显示的一级节点二级节点组合,最后一次性加载到listview显示上就可以啦。将所有的一级节点放在一个list中,二级节点放在一级节点的后面。写一个类来存放当前数据节点信息,而QList<NodeItem*> m_node_item_list;用来存放其下一级节点信息。最后逐条添加到listview的model中即可。
    树形model的加载方法可以借鉴下面的例子:如init_shoot_sequence_list_model(),该函数可以根据传入的true 或false可实现treeview与纯listview的转换。

class NodeItem{//    Q_OBJECTpublic:    NodeItem( int n_node_id, int n_region_id, QString n_region_name, int n_parent_id, int n_device_id, QString s_device_content, int n_level);    int get_node_id() { return mn_node_id; }    int get_region_id() { return mn_region_id; }    QString get_region_name() { return ms_region_name; }    int get_parent_id() { return mn_parent_id; }    int get_device_id() { return mn_device_id; }    QString get_device_content() { return ms_device_content; }    int get_shoot_sequence_level() { return mn_level; }    QList<NodeItem*> m_node_item_list;private:    int mn_node_id;    int mn_region_id;    QString ms_region_name;    int mn_parent_id;    int mn_device_id;    QString ms_device_content;    int mn_level;};
import QtQuick 2.3import QtQuick.Window 2.2Window {    visible: true    width: 480    height: 640    Rectangle {        anchors.fill: parent        ListModel{            id: objmodel        }        Component {            id: shoot_sequence_delegate            Item {                id: unit_item                width: parent.width                height: 30                Row{                    anchors.left: parent.left                    anchors.verticalCenter: parent.verticalCenter                    spacing: 8                    Text {                        id: tag_txt                        text: tag                        color: unit_item.ListView.isCurrentItem? "blue":"black"                        font.pixelSize: 20                    }                    Text {                        id: name_txt                        text: name                        color: unit_item.ListView.isCurrentItem? "blue":"black"                        font.pixelSize: 20                    }                }                MouseArea {                    id: mousearea                    anchors.fill: parent                    onClicked: {                        shoot_sequence_listview.currentIndex = index                    }                    onDoubleClicked: {                        shoot_sequence_listview.currentIndex = index                        var data = objmodel.get(shoot_sequence_listview.currentIndex);                        if( data.level_status === "0" ) {                            var n = data.model_index                            var n_device_node_count = shoot_sequences_list_model.get_device_node_count_from_list( data.model_index )                            if( data.visible_status === "true" ) {                                objmodel.setProperty(shoot_sequence_listview.currentIndex, "visible_status", "false")                                objmodel.setProperty(shoot_sequence_listview.currentIndex, "tag", "+")                                objmodel.remove( shoot_sequence_listview.currentIndex+1, n_device_node_count )                            } else {                                objmodel.setProperty(shoot_sequence_listview.currentIndex, "visible_status", "true")                                objmodel.setProperty(shoot_sequence_listview.currentIndex, "tag", "-")                                for( var j=0; j<n_device_node_count; j++ ) {                                    var n_node_id = shoot_sequences_list_model.get_node_id_from_list( n, j )                                    var n_region_id = shoot_sequences_list_model.get_region_id_from_list( n, j )                                    var s_region_name = shoot_sequences_list_model.get_region_name_from_list( n, j )                                    var n_parent_id = shoot_sequences_list_model.get_parent_id_from_list( n, j )                                    var n_device_id = shoot_sequences_list_model.get_device_id_from_list( n, j )                                    var s_device_content = shoot_sequences_list_model.get_device_content_from_list( n, j )                                    var n_shoot_level = shoot_sequences_list_model.get_shoot_sequence_level_from_list( n, j )                                    objmodel.insert(shoot_sequence_listview.currentIndex+j+1, {"name":""+s_device_content, "tag":"    ", "level_status":""+n_shoot_level, "regin_id": n_region_id, "visible_status":"true", "visible_status":"true", "model_index":""+n})                                }                            }                        }                    }                }            }        }        property int flag: 0        ListView {            id: shoot_sequence_listview            anchors.fill: parent            delegate: shoot_sequence_delegate            model:objmodel            interactive: false            focus: true            Component.onCompleted: {//                shoot_sequences_list_model.set_shoot_sequence_list_model( "26", true );//                init_shoot_sequence_list_model( true )                shoot_sequences_list_model.set_shoot_sequence_list_model( "26", false );                init_shoot_sequence_list_model( false )            }            function init_shoot_sequence_list_model(  b_last_level_status ) {                objmodel.clear()                if( b_last_level_status ) {                    var n_list_count = shoot_sequences_list_model.get_shoot_sequence_list_model_count()                    for( var i=0; i<n_list_count; i++ ) {                        var node_id = shoot_sequences_list_model.get_node_id( i )                        var region_id = shoot_sequences_list_model.get_region_id( i )                        var region_name = shoot_sequences_list_model.get_region_name( i )                        var parent_id = shoot_sequences_list_model.get_parent_id( i )                        var device_id = shoot_sequences_list_model.get_device_id( i )                        var device_content = shoot_sequences_list_model.get_device_content( i )                        var shoot_level = shoot_sequences_list_model.get_shoot_sequence_level( i )                        objmodel.append({"name":""+device_content, "tag":"  ", "level_status":""+shoot_level, "regin_id": region_id, "visible_status":"true", "model_index":"-1"})                    }                } else {                    var n_region_list_count = shoot_sequences_list_model.get_shoot_sequence_list_model_count()                    var n_device_node_count;                    for( var n=0; n<n_region_list_count; n++ ) {                        node_id = shoot_sequences_list_model.get_node_id( n )                        region_id = shoot_sequences_list_model.get_region_id( n )                        region_name = shoot_sequences_list_model.get_region_name( n )                        parent_id = shoot_sequences_list_model.get_parent_id( n )                        device_id = shoot_sequences_list_model.get_device_id( n )                        device_content = shoot_sequences_list_model.get_device_content( n )                        shoot_level = shoot_sequences_list_model.get_shoot_sequence_level( n )                        objmodel.append({"name":region_name, "tag":"-", "level_status":""+shoot_level, "regin_id": region_id, "visible_status":"true", "model_index":""+n})                        n_device_node_count = shoot_sequences_list_model.get_device_node_count_from_list( n )                        console.log("n_device_node_count: "+n_device_node_count)                        for( var j=0; j<n_device_node_count; j++ ) {                            var n_node_id = shoot_sequences_list_model.get_node_id_from_list( n, j )                            var n_region_id = shoot_sequences_list_model.get_region_id_from_list( n, j )                            var s_region_name = shoot_sequences_list_model.get_region_name_from_list( n, j )                            var n_parent_id = shoot_sequences_list_model.get_parent_id_from_list( n, j )                            var n_device_id = shoot_sequences_list_model.get_device_id_from_list( n, j )                            var s_device_content = shoot_sequences_list_model.get_device_content_from_list( n, j )                            var n_shoot_level = shoot_sequences_list_model.get_shoot_sequence_level_from_list( n, j )                            objmodel.append({"name":""+s_device_content, "tag":"    ", "level_status":""+n_shoot_level, "regin_id": n_region_id, "visible_status":"true", "model_index":""+n})                        }                    }                }            }        }    }}
0 0