上实现源码,这里的代码都是来自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
}
希望对大家有所帮助