Qt-QMl-自定义自己想要的TabView

简介: 上效果图

image.png

上实现源码,这里的代码都是来自Qt官方源码修改其中某一行内容


/*

 作者:张建伟

 时间:2018年4月8日

 简述:自定义TabView,主要实现Tab和实现内容重叠,不在占用独立空间

      该文件内容仅适用于某平台显示器使用

 */

import QtQuick 2.2

import QtQuick.Controls 1.4

import QtQuick.Controls.Styles 1.4

import QtQuick.Controls.Private 1.0

FocusScope

{

   id:root

   implicitWidth: 240

   implicitHeight: 150

   property int currentIndex: 0    //当前标签索引

   readonly property int count: __tabs.count       //当前标签数量

   property bool frameVisible: true                //标签边框可见

   property bool tabsVisible: true                 //标签是否可见

   property int tabPosition: Qt.TopEdge            //标签位置

   readonly property alias contentItem: stack      //标签内容视图属性          //这里翻译有问题

   default property alias data: stack.data         //内容

   property ListModel __tabs: ListModel { }

   property Component style: Settings.styleComponent(Settings.style, "DTabViewStyle.qml", root)

   property var __styleItem: loader.item

   onCurrentIndexChanged: __setOpacities()

   //添加标签

   function addTab(title, component)

   {

       return insertTab(__tabs.count, title, component)

   }

   //插入标签

   function insertTab(index, title, component)

   {

       var tab = tabcomp.createObject()

       tab.sourceComponent = component

       tab.title = title

       __tabs.insert(index, {tab: tab})

       tab.__inserted = true

       tab.parent = stack

       __didInsertIndex(index)

       __setOpacities()

       return tab

   }

   //移除标签

   function removeTab(index)

   {

       var tab = __tabs.get(index).tab

       __willRemoveIndex(index)

       __tabs.remove(index, 1)

       tab.destroy()

       __setOpacities()

   }

   //移动标签

   function moveTab(from, to)

   {

       __tabs.move(from, to, 1)

       if (currentIndex == from)

       {

           currentIndex = to

       }

       else

       {

           var start = Math.min(from, to)

           var end = Math.max(from, to)

           if (currentIndex >= start && currentIndex <= end)

           {

               if (from < to)

                   --currentIndex

               else

                   ++currentIndex

           }

       }

   }

   //获取标签

   function getTab(index)

   {

       var data = __tabs.get(index)

       return data && data.tab

   }

   function __willRemoveIndex(index)

   {

       if (count > 1 && (currentIndex > index || currentIndex == count -1))

           --currentIndex

   }

   function __didInsertIndex(index)

   {

       if (count > 1 && currentIndex >= index)

           currentIndex++

   }

   function __setOpacities() {

       for (var i = 0; i < __tabs.count; ++i)

       {

           var child = __tabs.get(i).tab

           child.visible = (i == currentIndex ? true : false)

       }

   }

   activeFocusOnTab: false

   Component

   {

       id: tabcomp

       Tab {}

   }

   TabBar

   {

       id: tabbarItem

       objectName: "tabbar"

       tabView: root

       style: loader.item

       anchors.top: parent.top

       anchors.left: root.left

       anchors.right: root.right

   }

   Loader

   {

       id: loader

       z: tabbarItem.z - 1

       sourceComponent: style

       property var __control: root

   }

   Loader

   {

       id: frameLoader

       z: tabbarItem.z - 1

       anchors.fill: parent

       //        anchors.topMargin: tabPosition === Qt.TopEdge && tabbarItem && tabsVisible  ? Math.max(0, tabbarItem.height - baseOverlap) : 0

       anchors.bottomMargin: tabPosition === Qt.BottomEdge && tabbarItem && tabsVisible ? Math.max(0, tabbarItem.height -baseOverlap) : 0

       sourceComponent: frameVisible && loader.item ? loader.item.frame : null

       property int baseOverlap: __styleItem ? __styleItem.frameOverlap : 0

       Item {

           id: stack

           anchors.fill: parent

           anchors.margins: (frameVisible ? frameWidth : 0)

           anchors.topMargin: anchors.margins + (style =="mac" ? 6 : 0)

           anchors.bottomMargin: anchors.margins

           property int frameWidth

           property string style

           property bool completed: false

           Component.onCompleted: {

               addTabs(stack.children)

               completed = true

           }

           onChildrenChanged: {

               if (completed)

                   stack.addTabs(stack.children)

           }

           function addTabs(tabs) {

               var tabAdded = false

               for (var i = 0 ; i < tabs.length ; ++i) {

                   var tab = tabs[i]

                   if (!tab.__inserted && tab.Accessible.role === Accessible.LayeredPane) {

                       tab.__inserted = true

                       // reparent tabs created dynamically by createObject(tabView)

                       tab.parent = stack

                       // a dynamically added tab should also get automatically removed when destructed

                       if (completed)

                           tab.Component.onDestruction.connect(stack.onDynamicTabDestroyed.bind(tab))

                       __tabs.append({tab: tab})

                       tabAdded = true

                   }

               }

               if (tabAdded)

                   __setOpacities()

           }

           function onDynamicTabDestroyed() {

               for (var i = 0; i < __tabs.count; ++i) {

                   if (__tabs.get(i).tab === this) {

                       __willRemoveIndex(i)

                       __tabs.remove(i, 1)

                       __setOpacities()

                       break

                   }

               }

           }

       }

       onLoaded: { item.z = -1 }

   }

   onChildrenChanged: stack.addTabs(root.children)

   states: [

       State {

           name: "Bottom"

           when: tabPosition === Qt.BottomEdge && tabbarItem != undefined

           PropertyChanges {

               target: tabbarItem

               anchors.topMargin: -frameLoader.baseOverlap

           }

           AnchorChanges {

               target: tabbarItem

               anchors.top: frameLoader.bottom

           }

       }

   ]

//    style: TabViewStyle

//    {

//        tab:Rectangle

//        {

//            id:t_root

//            //            implicitWidth: Math.max(text.width + 4, 80)

//            implicitWidth: 80

//            implicitHeight: 30

//            //            color: styleData.selected ? "steelblue" :"lightsteelblue"

//            property bool selectd: styleData.selected

//            Canvas

//            {

//                id: m_canvas

//                anchors.fill: parent

//                onPaint:

//                {

//                }

//            }

//        }

//    }

}

//BaseTabView

//{

//    style: TabViewStyle

//    {

//            }

//            Text {

//                id: text

//                anchors.centerIn: parent

//                text: styleData.title

//                font.family: "微软雅黑"

//                font.pixelSize: 18

//                color: styleData.selected ? "black" : "green"

//            }

//        }

//    }

//}

这里还有一个是美化的样式表,还是现在还有个问题,这个样式文件无法拷出来,必须还放到Qt的程序目录才可以


/*

 作者:张建伟

 时间:2018年4月8日

 简述:自定义TabView Style文件

 */

import QtQuick 2.2

import QtQuick.Controls 1.2

import QtQuick.Controls.Private 1.0

Style {

   readonly property TabView control: __control

   property bool tabsMovable: false

   property int tabsAlignment: Qt.AlignLeft

   property int tabOverlap: 1

   property int frameOverlap: 2

   property Component frame: Rectangle {

       color: "#dcdcdc"

       border.color: "#aaa"

       Rectangle {

           anchors.fill: parent

           color: "transparent"

           border.color: "#66ffffff"

           anchors.margins: 1

       }

   }

   property Component tab: Item {

       scale: control.tabPosition === Qt.TopEdge ? 1 : -1

       property int totalOverlap: tabOverlap * (control.count - 1)

       property real maxTabWidth: control.count > 0 ? (styleData.availableWidth + totalOverlap) / control.count : 0

       //implicitWidth: Math.round(Math.min(maxTabWidth, textitem.implicitWidth + 20))

       implicitWidth: 80

       implicitHeight: Math.round(textitem.implicitHeight + 10)

       Item {

           id: m_Item

           anchors.fill: parent

           anchors.bottomMargin: styleData.selected ? 0 : 1

           Canvas

           {

               id: m_Canvas

               anchors.fill: parent

               property bool isSelectd: styleData.selected

               property int m_width: m_Item.width

               property int  m_height: m_Item.height

               onPaint:

               {

                   var  ctx = getContext("2d");

                   ctx.width = m_width

                   ctx.clearRect(0,0,2000,2000);

                   ctx.height = m_height

                   ctx.lineWidth = 2.0;

                   ctx.lineJoin = 'miter';

                   ctx.strokeStyle = "#00FF00";

                   ctx.fillStyle = "#00FF00";

                   ctx.moveTo(1,0);

                   ctx.lineTo(m_Item.width-1,0);

                   ctx.lineTo(70,m_Item.height-1);

                   ctx.lineTo(10,m_Item.height-1);

                   ctx.lineTo(1,0);

                   if(isSelectd)

                   {

                       ctx.fill();

                   }

                   else

                   {

                       ctx.stroke();

                   }

               }

           }

       }

       Text {

           id: textitem

           anchors.fill: parent

           anchors.leftMargin: 4

           anchors.rightMargin: 4

           verticalAlignment: Text.AlignVCenter

           horizontalAlignment: Text.AlignHCenter

           text: styleData.title

           elide: Text.ElideMiddle

           renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering

           scale: control.tabPosition === Qt.TopEdge ? 1 : -1

           font.bold: true

           font.family: "微软雅黑"

           font.pixelSize: 16

           color: styleData.selected ? "black" : "#00FF00"

           Rectangle {

               anchors.centerIn: parent

               width: textitem.paintedWidth + 6

               height: textitem.paintedHeight + 4

               visible: (styleData.activeFocus && styleData.selected)

               radius: 3

               color: "#224f9fef"

               border.color: "#47b"

           }

       }

   }

   property Component leftCorner: null

   property Component rightCorner: null

   property Component tabBar: null

}





希望对大家有所帮助


目录
相关文章
|
6月前
|
存储 机器学习/深度学习 人工智能
Qt魔法书:打造自定义鼠标键盘脚本(二)
Qt魔法书:打造自定义鼠标键盘脚本
214 0
|
6月前
QT自定义信号,信号emit,信号参数注册
使用signals声明返回值是void在需要发送信号的地方使用emit 信号名字(参数)进行发送在需要链接的地方使用connect进行链接ct进行链接。
67 0
QT自定义信号,信号emit,信号参数注册
|
6月前
Qt提升控件类为自定义类
Qt提升控件类为自定义类
228 0
10 QT - 自定义信号和槽
10 QT - 自定义信号和槽
61 0
|
1月前
(8)Qt中的自定义信号
本文介绍了如何在Qt框架中创建和使用自定义信号,并通过一个父子窗口切换的示例来展示自定义信号的实现和应用。
69 3
(8)Qt中的自定义信号
|
1月前
(7)Qt中的自定义槽(函数)
这篇文章介绍了在Qt中如何定义和使用自定义槽函数,包括类成员函数、静态类成员函数、全局函数和lambda表达式作为槽函数的示例,以及使用lambda表达式时的注意事项。
39 2
(7)Qt中的自定义槽(函数)
|
3月前
|
搜索推荐 C++
【Qt 学习笔记】Qt窗口 | 对话框 | 创建自定义对话框
【Qt 学习笔记】Qt窗口 | 对话框 | 创建自定义对话框
73 4
|
3月前
【qt】自定义对话框(2)
【qt】自定义对话框(2)
24 0
|
3月前
【qt】自定义对话框(1)
【qt】自定义对话框(1)
30 0
|
4月前
|
C++
Qt中的信号与槽如何学习?(包括自定义信号)这篇文章告诉你
以现实中的事件来举例的话,例如有两把不同颜色的信号枪,分别是红色,绿色,打响不通颜色的信号枪会触发不同的槽发生,比如说打响红色这个人就跑步,绿色就走步,但是还有一个很重要的机制,那就是连接,我们需要把信号枪去跟这个人的动作连接起来。 如果上面理解没问题的话我们可以把信号和槽看成两个工具,我们最重要的是如何去把这两个工具连接起来。 它的作用可以让我们更加灵活的去使用不同窗口间的切换以及某些事件的连接。

相关实验场景

更多

推荐镜像

更多