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

}





希望对大家有所帮助


目录
相关文章
|
1月前
|
存储 机器学习/深度学习 人工智能
Qt魔法书:打造自定义鼠标键盘脚本(二)
Qt魔法书:打造自定义鼠标键盘脚本
35 0
|
3月前
QT自定义信号,信号emit,信号参数注册
使用signals声明返回值是void在需要发送信号的地方使用emit 信号名字(参数)进行发送在需要链接的地方使用connect进行链接ct进行链接。
19 0
QT自定义信号,信号emit,信号参数注册
|
3月前
Qt提升控件类为自定义类
Qt提升控件类为自定义类
|
4月前
|
搜索推荐 C++ 索引
C++ Qt开发:QItemDelegate自定义代理组件
在Qt中,`QStyledItemDelegate` 类是用于创建自定义表格视图(如`QTableView`和`QTableWidget`)的委托类,允许你自定义表格中每个单元格的外观和交互。`QStyledItemDelegate` 是`QItemDelegate` 的子类,提供了更现代、更易用的接口。此处我们将实现对`QTableView`表格组件的自定义代理功能,例如默认情况下表格中的缺省代理就是一个编辑框,我们只能够在编辑框内输入数据,而有时我们想选择数据而不是输入,此时就需要重写编辑框实现选择的效果,代理组件常用于个性化定制表格中的字段类型。
37 0
C++ Qt开发:QItemDelegate自定义代理组件
|
5月前
10 QT - 自定义信号和槽
10 QT - 自定义信号和槽
34 0
|
API 计算机视觉
Qt实用技巧:自定义窗口标题栏
Qt实用技巧:自定义窗口标题栏
Qt实用技巧:自定义窗口标题栏
|
3月前
Qt6学习笔记五(自定义对话框、QMessageBox、QColorDialog、QFileDialog、QFontDialog)
Qt6学习笔记五(自定义对话框、QMessageBox、QColorDialog、QFileDialog、QFontDialog)
41 0
|
1月前
|
开发框架 Linux API
Qt魔法书:打造自定义鼠标键盘脚本(一)
Qt魔法书:打造自定义鼠标键盘脚本
23 0
|
1月前
使用代码实现QT自定义布局
使用代码实现QT自定义布局
|
3月前
Qt6自定义QML控件的方式
Qt6自定义QML控件的方式
69 1

热门文章

最新文章

推荐镜像

更多