• QML + KDDockWidget 实现 tabwidget效果( 窗口可独立浮动和缩放)


    前言

    前面文章介绍过在QML中使用ListView实现TabBar标签拖拽交换位置效果(文章在这里

    先在此基础上升级一下,结合KDDockWidget做一个可浮动的窗口效果。

    关于KDDockWidget的介绍,以前的文章有写过,可参考:
    qml dockwidget窗口停靠
    KDDockWidgets源码编译及安装

    KDDockWidget是第三方开源项目,可以用于实现QML中Dock窗口效果,Qt本身不支持QML的Dock效果,所以正好弥补这部分空缺。而KDDockWidget中其实是支持Tab合并效果,但是在实际使用过程中遇到很多问题,该功能并不是很完善,所以索性自己使用QML来实现tabbar效果,然后结合KDDockWidget,可将每个tab页面进行单独的浮动和缩放。

    先看效果:
    在这里插入图片描述


    本文Demo下载
    点击下载

    KDDockWidget动态库编译环境 VS2019
    Demo使用环境 Qt5.15.2+VS2019


    正文

    关于ListView实现一个tabbar移动效果,前面文章有介绍过,这里简单贴个代码:

    ListView{
        id:tabBar
         anchors.left: parent.left
         anchors.right: parent.right
         anchors.rightMargin: 66
         interactive: false
         anchors.leftMargin: 20
         z:15
         height: 30
         spacing: 1
         orientation:ListView.Horizontal
         currentIndex: -1;
         move: Transition {
             NumberAnimation { property: "x"; duration: 150 }
         }
         moveDisplaced: Transition {
             NumberAnimation { property: "x"; duration: 150 }
         }
         model:ListModel{
             id:tabModel
             onCountChanged: {
                 if(count > 0)
                     tabBar.currentIndex = count-1
             }
         }
    
         delegate: TabButton{
             id:tabButton
             height: 30
             width: 120
    
             contentItem: Text {
                 font.pixelSize: 14
                 font.family: "Source Han Sans SC"
                 text: dockname
                 horizontalAlignment: Text.AlignHCenter
                 verticalAlignment: Text.AlignVCenter
                 color: tabBar.currentIndex === index ? "#3692F0" :"#525252"
                 elide: Text.ElideMiddle
             }
    
             background:Item{
                 Rectangle {
                     color: tabBar.currentIndex === index ? "#171717" : "transparent"
                     border.width: tabBar.currentIndex === index ? 1 : 0
                     border.color: "#404040"
                     height: parent.height+3
                     width: parent.width
                     x:-1;y:-2
                     Rectangle{
                         y:parent.height-1
                         width: parent.width
                         height: 3
                         color: "#171717"
                         visible: tabBar.currentIndex === index
                         z:20
                     }
                 }
             }
    
             MouseArea{
                 id:ma2
                 anchors.fill: parent
                 preventStealing: true
                 hoverEnabled: true
                 onPositionChanged: {
                     var other_index = tabBar.indexAt(ma2.mouseX + tabButton.x, ma2.mouseY + tabButton.y);
                     if (other_index !== -1 && pressed) {
                         if (index !== other_index) {
                             tabModel.move(index, other_index,1);
                             tabBar.positionViewAtIndex(other_index,ListView.Center)
                         }
                     }
                 }
                 onClicked: {
                     tabBar.currentIndex = index
                 }
             }
         }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    接下来看每个单独的dock窗口

    import QtQuick 2.0
    import QtQuick.Controls 2.15
    import com.kdab.dockwidgets 1.0 as KDDW
    
    KDDW.MainWindowLayout{
        id:panel
        property string dockName: "dock#1"
        uniqueName:"MainLayout1"
    
        KDDW.DockWidget{
            id:dock1
            uniqueName:"dock#1"
            property bool isFirstFloating: true
            property bool floating: false
    
            Rectangle{
                color:"#171717"
    
                Label{
                    text:"This is Dock #1"
                    anchors.centerIn: parent
                    font.pixelSize:40
                    color: "white"
                }
            }
    
            onSigFloatClicked:{
                dock1.floating = !dock1.floating
                if(!dock1.isFloating){
                    removeTimer.name = panel.dockName
                    removeTimer.start()
                }
                else{
                    addData(panel.dockName)
                }
    
            }
            //关闭按钮已在DockTitleBar中隐藏
    //        onSigCloseClicked:{
    //            removeData(panel.dockName)
    //        }
        }
    
        Component.onCompleted: {
            addDockWidget(dock1,KDDW.KDDockWidgets.Location_OnLeft)
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    由于我们是自定义的tabbar效果,所以这里没有用KDDockWidget提供的addDockWidgetAsTab接口,而是直接使用addDockWidget,每个tab page是一个单独的MainWindowLayout,包含一个独立的DockWidget。浮动窗口功能是直接点击floating button来调用相应接口实现。

    代码中用到的KDDockWidget是在源码基础上进行部分修改后重新编译成的动态库,可根据实际项目需求,对源码进行适当修改,若需要修改后的源码,可联系我提供。

    本文只实现了窗口的浮动效果,没有添加窗口关闭,若有需要,可在自动以标题栏中将关闭按钮显示出来,并添加其逻辑即可。

    不解之处,可私信。


    本文Demo下载
    点击下载

    KDDockWidget动态库编译环境 VS2019


  • 相关阅读:
    深入理解算法的时间复杂度
    【强化学习高阶技巧】Experience Replay经验回报
    因为manifest.json文件引起的 android-chrome-192x192.png 404 (Not Found)
    Java8——Lambda、stream API
    Shell入门
    第十四届蓝桥杯大赛B组 JAVA 蜗牛 (递归剪枝)
    经典查找算法
    ArcgisForJS如何使用ArcGIS Server发布的GP服务?
    MySQL-8.0 事务隔离级别
    vue 封装element公共组件 +后端联调
  • 原文地址:https://blog.csdn.net/luoyayun361/article/details/128191023