需上篇,用标签改了下拉菜单后,应需求,不能将标签栏的标签拉到菜单按钮后,且菜单按钮不能被移动,新增页面后跳转至该新页面,以及点击下拉菜单被隐藏标签会跳转至该标签的页面,做了以下修改及主要代码有下。
1、修改之前的标签改为按钮,按钮的位置实时变化
#创建标签菜单按钮
self.btn_menu = QPushButton(self)
self.btn_menu.hide()
self.btn_menu_state = 0
def tabMenuState(self):
self.btn_menu.setText('<<'+str(self.l+self.r))
self.btn_menu.move(self.barWidth-self.tabbar.tabSizeHint(0).height()*2-2, 0)
self.btn_menu.resize(self.tabbar.tabSizeHint(0).height()*2, self.tabbar.tabSizeHint(0).height())
if self.btn_menu_state == 0 and self.l+self.r > 0:
self.btn_menu_state = 1
self.btn_menu.show()
self.barWidth += self.tabbar.tabSizeHint(0).height()*2
print('添加菜单')
elif self.btn_menu_state == 1 and self.l+self.r == 0:
self.btn_menu_state = 0
self.btn_menu.hide()
self.barWidth -= self.tabbar.tabSizeHint(0).height()*2
print('移除菜单')
2、新增添加页面的按钮,可输入页面名称
def addTabs(self):
hide_tab = mw.tabs.tabs_text.index(mw.tabs.tabText(mw.tabs.page))
print(mw.tabs.tabs_text.index(mw.tabs.tabText(mw.tabs.page)))
print(len(mw.tabs.tabs_show_status))
if mw.tabs.barWidth + 130 > mw.w :
mw.tabs.tabs_show_status[hide_tab] = 0
mw.tabs.r += 1
#显示或隐藏tab菜单
mw.tabs.tabMenuState()
#根据calcutab()展示tab
mw.tabs.updatetab()
#根据calcutab()隐藏tab至tabMenu
mw.tabs.updatetabMenu()
print('有隐藏添加')
if len(self.cb.displayText()) == 0 :
mw.tabs.addTabs(len(mw.tabs.tabs_show_status), '空白页面'+str(len(mw.tabs.tabs_show_status)))
print('无名添加')
print(mw.tabs.tabs_text)
else:
if len(self.cb.displayText()) > 13 :
tabtext = self.cb.displayText()
mw.tabs.addTabs(len(mw.tabs.tabs_show_status), tabtext[0:13])
else :
mw.tabs.addTabs(len(mw.tabs.tabs_show_status), self.cb.displayText())
print('有名添加')
print(mw.tabs.tabs_show_status)
""" print(mw.tabs.tabs_show_status)
print(self.cb.displayText()) """
#显示或隐藏tab菜单
mw.tabs.tabMenuState()
#根据calcutab()展示tab
mw.tabs.updatetab()
#根据calcutab()隐藏tab至tabMenu
mw.tabs.updatetabMenu()
#跳转至新页面
jump = mw.tabs.indexOf(mw.tabs.tabs_page[len(mw.tabs.tabs_page)-1])
mw.tabs.setCurrentIndex(jump)
mw.tabs.update()
self.reject()
3、页面可删除
def delTabs(self,index):
""" self.tabs_show_status = {}
self.tabs_text = []
self.tabs_page = {}
self.tabs_width = {}
self.tabs_menu_item = {} """
print('----------------------------------------')
print(self.tabs_show_status)
print(self.tabs_text)
print(self.tabs_page)
print(self.tabs_width)
print(self.tabs_menu_item)
print('----------------------------------------------')
del_tab = mw.tabs.tabs_text.index(mw.tabs.tabText(index))
self.barWidth -= self.tabs_width[del_tab]
self.menu.removeAction(self.tabs_menu_item[del_tab])
self.tabs_text.pop(del_tab)
for i in range(0,len(self.tabs_show_status)-del_tab-1):
#将被删除标签后的标签数据前移
self.tabs_show_status[del_tab+i] = self.tabs_show_status[del_tab+i+1]
self.tabs_page[del_tab+i] = self.tabs_page[del_tab+i+1]
self.tabs_width[del_tab+i] = self.tabs_width[del_tab+i+1]
self.tabs_menu_item[del_tab+i] = self.tabs_menu_item[del_tab+i+1]
#移除最后一个数据
self.tabs_show_status.pop(len(self.tabs_show_status)-1)
self.tabs_page.pop(len(self.tabs_page)-1)
self.tabs_width.pop(len(self.tabs_width)-1)
self.tabs_menu_item.pop(len(self.tabs_menu_item)-1)
#更新数据
self.page -= 1
#移除页面
self.removeTab(index)
self.update()
print(self.tabs_show_status)
print(self.tabs_text)
print(self.tabs_page)
print(self.tabs_width)
print(self.tabs_menu_item)
print('-----------------------------------------------')
以上为主要修改部分,该代码仅供参考,为本人学习,练习所作,非专业教学。
完整代码:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtTest import QTest
import sys
from functools import partial
class Singleton(object):
def __init__(self, cls):
self._cls = cls
self._instance = {}
def __call__(self):
if self._cls not in self._instance:
self._instance[self._cls] = self._cls()
return self._instance[self._cls]
class riLog(QDialog):
def __init__(self):
super().__init__()
self.setWindowFlags(Qt.FramelessWindowHint |
Qt.WindowMinimizeButtonHint)
self.resize(700, 50)
self.cb = QLineEdit(self)
self.cb.setObjectName("cb")
self.cb.resize(550, 30)
self.cb.move(10, 10)
self.cb.setPlaceholderText("输入标签名称")
self.btn = QPushButton(self)
self.btn.setText('添加页面')
self.btn.resize(120, 40)
self.btn.move(570, 5)
self.btn.setObjectName("btn1")
self.btn.clicked.connect(self.addTabs)
Qss2 = '''
QPushButton#btn1
{
border-radius: 4px;
border:1px solid rgb(0,0,0);
font-size:20px;
background-color:#ffffff;
}
QComboBox#cb
{
}
'''
self.setStyleSheet(Qss2)
def openDialog(self):
self.setWindowTitle("Dialog")
self.setWindowModality(Qt.ApplicationModal)
self.exec_()
#自定义添加页面
def addTabs(self):
hide_tab = mw.tabs.tabs_text.index(mw.tabs.tabText(mw.tabs.page))
print(mw.tabs.tabs_text.index(mw.tabs.tabText(mw.tabs.page)))
print(len(mw.tabs.tabs_show_status))
if mw.tabs.barWidth + 130 > mw.w :
mw.tabs.tabs_show_status[hide_tab] = 0
mw.tabs.r += 1
#显示或隐藏tab菜单
mw.tabs.tabMenuState()
#根据calcutab()展示tab
mw.tabs.updatetab()
#根据calcutab()隐藏tab至tabMenu
mw.tabs.updatetabMenu()
print('有隐藏添加')
if len(self.cb.displayText()) == 0 :
mw.tabs.addTabs(len(mw.tabs.tabs_show_status), '空白页面'+str(len(mw.tabs.tabs_show_status)))
print('无名添加')
print(mw.tabs.tabs_text)
else:
if len(self.cb.displayText()) > 13 :
tabtext = self.cb.displayText()
mw.tabs.addTabs(len(mw.tabs.tabs_show_status), tabtext[0:13])
else :
mw.tabs.addTabs(len(mw.tabs.tabs_show_status), self.cb.displayText())
print('有名添加')
print(mw.tabs.tabs_show_status)
""" print(mw.tabs.tabs_show_status)
print(self.cb.displayText()) """
#显示或隐藏tab菜单
mw.tabs.tabMenuState()
#根据calcutab()展示tab
mw.tabs.updatetab()
#根据calcutab()隐藏tab至tabMenu
mw.tabs.updatetabMenu()
#跳转至新页面
jump = mw.tabs.indexOf(mw.tabs.tabs_page[len(mw.tabs.tabs_page)-1])
mw.tabs.setCurrentIndex(jump)
mw.tabs.update()
self.reject()
#重写QtabWidget
class TabWidget(QTabWidget):
def __init__(self):
super(TabWidget,self).__init__()
self.tabbar = TabBar(self)
self.setTabBar(self.tabbar)
self.setTabsClosable(True)
#self.setUsesScrollButtons(False)
#工具数据
self.tabs_show_status = {}
self.tabs_text = []
self.tabs_page = {}
self.tabs_width = {}
self.tabs_menu_item = {}
self.r=0
self.l=0
self.barWidth=0
self.page=-1
#创建标签菜单按钮
self.btn_menu = QPushButton(self)
self.btn_menu.hide()
self.btn_menu_state = 0
self.menu = QMenu(self)
self.menu_tab = QAction('菜单',self)
self.menu.addAction(self.menu_tab)
#self.btn_menu = QPushButton(self)
""" self.btn_menu.resize(30, 30)
self.btn_menu.setText('菜单')
self.btn_menu.move(0, 0) """
self.btn_menu.clicked.connect(self.onClicked)
self.tabCloseRequested.connect(self.delTabs)
def onClicked(self):
self.menu.exec_(QCursor.pos())
def delTabs(self,index):
""" self.tabs_show_status = {}
self.tabs_text = []
self.tabs_page = {}
self.tabs_width = {}
self.tabs_menu_item = {} """
print('----------------------------------------')
print(self.tabs_show_status)
print(self.tabs_text)
print(self.tabs_page)
print(self.tabs_width)
print(self.tabs_menu_item)
print('----------------------------------------------')
del_tab = mw.tabs.tabs_text.index(mw.tabs.tabText(index))
self.barWidth -= self.tabs_width[del_tab]
self.menu.removeAction(self.tabs_menu_item[del_tab])
self.tabs_text.pop(del_tab)
for i in range(0,len(self.tabs_show_status)-del_tab-1):
#将被删除标签后的标签数据前移
self.tabs_show_status[del_tab+i] = self.tabs_show_status[del_tab+i+1]
self.tabs_page[del_tab+i] = self.tabs_page[del_tab+i+1]
self.tabs_width[del_tab+i] = self.tabs_width[del_tab+i+1]
self.tabs_menu_item[del_tab+i] = self.tabs_menu_item[del_tab+i+1]
#移除最后一个数据
self.tabs_show_status.pop(len(self.tabs_show_status)-1)
self.tabs_page.pop(len(self.tabs_page)-1)
self.tabs_width.pop(len(self.tabs_width)-1)
self.tabs_menu_item.pop(len(self.tabs_menu_item)-1)
#更新数据
self.page -= 1
#移除页面
self.removeTab(index)
self.update()
print(self.tabs_show_status)
print(self.tabs_text)
print(self.tabs_page)
print(self.tabs_width)
print(self.tabs_menu_item)
print('-----------------------------------------------')
#添加页面方法
def addTabs(self,index,text):
self.tabs_page[index] = QWidget()
self.addTab(self.tabs_page[index], text)
self.tabs_text.append(text)
self.tabs_width[index] = self.tabbar.tabSizeHint(self.page+1).width()
self.tabs_show_status[index] = 1
#删除按钮
#self.tabbar.setTabButton(index, self.tabbar.RightSide, self.tabs_page[index])
#创建菜单
self.tabs_menu_item[index] = QAction(text,self)
self.menu.addAction(self.tabs_menu_item[index])
self.tabs_menu_item[index].triggered.connect(partial(self.menuJump,index))
self.btn_menu.resize(25, 30)
#窗口宽度
self.barWidth += self.tabs_width[index]
self.page += 1
#最右与最左tab的宽度
self.tab_Rwidth = self.tabbar.tabSizeHint(self.page).width()
self.tab_Lwidth = self.tabbar.tabSizeHint(0).width()
self.tabMenuState()
print(self.tabs_width)
print(self.tabs_show_status)
def update(self):
i=0
while self.barWidth != mw.w and i <= self.r+self.l:
i += 1
#计算展示的tab
self.calcutab()
#显示或隐藏tab菜单
self.tabMenuState()
#根据calcutab()展示tab
self.updatetab()
#根据calcutab()隐藏tab至tabMenu
self.updatetabMenu()
def tabMenuState(self):
self.btn_menu.setText('<<'+str(self.l+self.r))
self.btn_menu.move(self.barWidth-self.tabbar.tabSizeHint(0).height()*2-2, 0)
self.btn_menu.resize(self.tabbar.tabSizeHint(0).height()*2, self.tabbar.tabSizeHint(0).height())
if self.btn_menu_state == 0 and self.l+self.r > 0:
self.btn_menu_state = 1
self.btn_menu.show()
self.barWidth += self.tabbar.tabSizeHint(0).height()*2
print('添加菜单')
elif self.btn_menu_state == 1 and self.l+self.r == 0:
self.btn_menu_state = 0
self.btn_menu.hide()
self.barWidth -= self.tabbar.tabSizeHint(0).height()*2
print('移除菜单')
#计算需要展示的页面
def calcutab(self):
#当tab宽度大于窗口宽度时
if self.barWidth > mw.w:
self.tab_index = self.currentIndex()
#当前页面的右边tab比左边多
if (self.page-self.tab_index) >= self.tab_index:
""" index = 0
while self.tabs_show_status[len(self.tabs_show_status)-self.r-1+index] == 0 :
index += 1
self.tabs_show_status[len(self.tabs_show_status)-self.r-1+index] = 0 """
hide_tab = self.tabs_text.index(mw.tabs.tabText(self.page))
self.tabs_show_status[hide_tab] = 0
#更新数据
self.r += 1
self.tab_Rwidth = self.tabbar.tabSizeHint(self.page).width()
print('调用删右边')
print(self.tabs_show_status)
#当前页面的右边tab比左边少
else :
""" index = 0
while self.tabs_show_status[self.l-index] == 0 :
index += 1
self.tabs_show_status[self.l-index] = 0 """
hide_tab = self.tabs_text.index(mw.tabs.tabText(0))
self.tabs_show_status[hide_tab] = 0
#更新数据
self.l += 1
print('调用删左边')
print(self.tabs_show_status)
#当tab宽度小于窗口宽度时
elif self.barWidth+130 < mw.w and len(self.tabs_show_status)-self.r-self.l < len(self.tabs_show_status):
self.tab_index = self.currentIndex()
#当前页面的右边tab比左边多
if (self.page-self.tab_index) >= self.tab_index :
if self.l > 0 :
index = 0
while self.tabs_show_status[self.l-1+1-index] == 1 and self.l-1+1-index < len(self.tabs_show_status)-1:
index += 1
self.tabs_show_status[self.l-1+1-index] = 1
#更新数据
self.l -= 1
print('调用1左添加' )
print(self.tabs_show_status)
elif self.l == 0 :
index = 0
while self.tabs_show_status[len(self.tabs_page)-self.r-1+index] == 1 and len(self.tabs_page)-self.r-1+index < len(self.tabs_show_status)-1:
index += 1
self.tabs_show_status[len(self.tabs_page)-self.r-1+index] = 1
#更新数据
self.r -= 1
print('调用1右添加' )
print(self.tabs_show_status)
#当前页面的右边tab比左边少
elif (self.page-self.tab_index) < self.tab_index:
if self.r > 0 :
index = 0
while self.tabs_show_status[len(self.tabs_page)-self.r-1+index] == 1 and len(self.tabs_page)-self.r-1+index < len(self.tabs_page)-1:
index += 1
self.tabs_show_status[len(self.tabs_page)-self.r-1+index] = 1
#更新数据
self.r -= 1
print('调用2右添加' )
print(self.tabs_show_status)
elif self.r == 0 :
index = 0
while self.tabs_show_status[self.l-1+1-index] == 1 and self.l-1+1-index < len(self.tabs_show_status)-1:
index += 1
self.tabs_show_status[self.l-1+1-index] = 1
#更新数据
self.l -= 1
print('调用2左添加' )
print(self.tabs_show_status)
def updatetab(self):
for i in range(0,(len(self.tabs_page))):
#需添加页面
if self.indexOf(self.tabs_page[i]) == -1 and self.tabs_show_status[i] == 1:
x = 0
while self.indexOf(self.tabs_page[i+x]) == -1 and i+x < len(self.tabs_show_status)-1:
x += 1
if x > 0 and i+x != len(self.tabs_show_status)-1:
self.insertTab(self.indexOf(self.tabs_page[i+x]),self.tabs_page[i], str(self.tabs_text[i]))
else :
self.addTab(self.tabs_page[i], str(self.tabs_text[i]))
#更新数据
self.barWidth += self.tabs_width[i]
self.page += 1
print('调用3')
#需隐藏页面
if self.indexOf(self.tabs_page[i]) > -1 and self.tabs_show_status[i] == 0:
self.removeTab(self.indexOf(self.tabs_page[i]))
#更新数据
self.barWidth -= self.tabs_width[i]
self.page -= 1
self.tabMenuState()
def updatetabMenu(self):
for i in range(0,(len(self.tabs_page))):
#菜单需隐藏页面
if self.tabs_show_status[i] == 1:
self.tabs_menu_item[i].setVisible(False)
#菜单需显示页面
if self.tabs_show_status[i] == 0:
self.tabs_menu_item[i].setVisible(True)
def menuJump(self,sri):
print(self.tabs_show_status)
#所点tab右边
if sri > self.l :
self.tabs_show_status[sri] = 1
hide_tab = self.tabs_text.index(mw.tabs.tabText(0))
""" index=0
while self.tabs_show_status[index] == 0 :
index += 1 """
self.tabs_show_status[hide_tab] = 0
self.l += 1
self.r -= 1
elif sri < self.l :
self.tabs_show_status[sri] = 1
""" index=len(self.tabs_show_status)-1
while self.tabs_show_status[index] == 0 :
index -= 1 """
hide_tab = self.tabs_text.index(mw.tabs.tabText(self.page))
self.tabs_show_status[hide_tab] = 0
self.l -= 1
self.r += 1
self.update()
jump = self.indexOf(self.tabs_page[sri])
#跳转至新页面
self.setCurrentIndex(jump)
print('----------')
print(sri)
print('----------')
""" #根据calcutab()展示tab
self.updatetab()
#根据calcutab()隐藏tab至tabMenu
self.updatetabMenu() """
print('调用跳转')
print(self.tabs_show_status)
class TabBar(QTabBar):
def __init__(self,parent,*args,**kwargs):
QTabBar.__init__(self,parent,*args,**kwargs)
#self.setTabsClosable(True)
self.tabMoved.connect(self.tabMovedCode)
self.btn_menu_state=1
qss = '''
QTabBar::tab{
max-width:130;
min-width:50
}
'''
self.setStyleSheet(qss)
def tabMovedCode(self,x,y,):
""" self.tabs_show_status = {}
self.tabs_text = []
self.tabs_page = {}
self.tabs_width = {}
self.tabs_menu_item = {} """
""" print(move)
print(moved) """
print('--------------------------------')
print(mw.tabs.tabs_show_status)
print(mw.tabs.tabs_text)
print(mw.tabs.tabs_page)
print(mw.tabs.tabs_width)
print(mw.tabs.tabs_menu_item)
#获取被移动的tab在本地数组的位置
move = mw.tabs.tabs_text.index(mw.tabs.tabText(x)) #选择的tab
moved = mw.tabs.tabs_text.index(mw.tabs.tabText(y)) #被移动的副tab
#修改其数据
mw.tabs.tabs_show_status[999] = mw.tabs.tabs_show_status[move]
mw.tabs.tabs_show_status[move] = mw.tabs.tabs_show_status[moved]
mw.tabs.tabs_show_status[moved] = mw.tabs.tabs_show_status[999]
del mw.tabs.tabs_show_status[999]
char = mw.tabs.tabs_text[moved]
mw.tabs.tabs_text[moved] = mw.tabs.tabs_text[move]
mw.tabs.tabs_text[move] = char
mw.tabs.tabs_page[999] = mw.tabs.tabs_page[move]
mw.tabs.tabs_page[move] = mw.tabs.tabs_page[moved]
mw.tabs.tabs_page[moved] = mw.tabs.tabs_page[999]
del mw.tabs.tabs_page[999]
mw.tabs.tabs_width[999] = mw.tabs.tabs_width[move]
mw.tabs.tabs_width[move] = mw.tabs.tabs_width[moved]
mw.tabs.tabs_width[moved] = mw.tabs.tabs_width[999]
del mw.tabs.tabs_width[999]
mw.tabs.tabs_menu_item[999] = mw.tabs.tabs_menu_item[move]
mw.tabs.tabs_menu_item[move] = mw.tabs.tabs_menu_item[moved]
mw.tabs.tabs_menu_item[moved] = mw.tabs.tabs_menu_item[999]
""" mw.tabs.tabs_menu_item[move].triggered.connect(partial(mw.tabs.menuJump,move))
mw.tabs.tabs_menu_item[moved].triggered.connect(partial(mw.tabs.menuJump,moved)) """
del mw.tabs.tabs_menu_item[999]
for i in range (0,len(mw.tabs.tabs_menu_item)):
mw.tabs.tabs_menu_item[i].triggered.connect(partial(mw.tabs.menuJump,i))
print(move)
print(moved)
print('--------------------------------')
print(mw.tabs.tabs_show_status)
print(mw.tabs.tabs_text)
print(mw.tabs.tabs_page)
print(mw.tabs.tabs_width)
print(mw.tabs.tabs_menu_item)
def btnMenu(self):
self.btn_menu[0] = QPushButton(self)
self.btn_menu.setText('菜单')
self.btn_menu.resize(30, 30)
#self.btn_menu.move(500, 500)
print('菜单创建')
class MainWindow(QMainWindow):
_instance = None
def __new__(cls, *args, **kw):
""" if cls._instance is None:
cls._instance = QMainWindow.__new__(cls, *args, **kw)
return cls._instance """
if not hasattr(cls,'mw'):
orig = super(MainWindow,cls)
cls.mw = orig.__new__(cls,*args, **kw)
return cls.mw
def __init__(self,parent=None, *args, **kwargs):
QMainWindow.__init__(self, parent, *args,**kwargs)
#新
self.x = str(0)
AllWidget = QWidget()
Alllayout = QVBoxLayout()
# 设置控件无边界 无边框
Alllayout.setSpacing(0)
Alllayout.setContentsMargins(0, 0, 0, 0)
AllWidget.setLayout(Alllayout)
self.tabs = TabWidget()
self.tabs.setMovable(True)
self.tb = self.addToolBar("File")
self.addtabs = QAction("添加页面",self)
self.tb.addAction(self.addtabs)
self.dialog = riLog()
self.addtabs.triggered.connect(self.dialog.openDialog)
for i in range(0,10):
self.x += str(i)
self.tabs.addTabs(i, "Tab"+self.x)
self.setCentralWidget(self.tabs)
self.resize(2000, 1000)
self.tabs.move(100,100)
""" self.btn = QPushButton(self)
self.btn.move(0,0) """
#Alllayout.addWidget(self.tabs.tabbar)
Alllayout.addWidget(self.tabs)
#Alllayout.addWidget(self.btn_menu)
self.setCentralWidget(AllWidget)
def resizeEvent(self, event):
self.w = event.size().width()
self.h = event.size().height()
#print('刷新')
self.tabs.update()
def changeEvent(self, event):
self.tabs.update()
#print('最大化')
print(self.w)
if __name__ == '__main__':
app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
效果如下: