IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> PyQt5模仿火狐,eclipse的标签栏tab隐藏菜单 -> 正文阅读

[开发工具]PyQt5模仿火狐,eclipse的标签栏tab隐藏菜单

最近在学习使用pyqt5制作窗口界面,实习正好有一个实习项目是做一个类似eclipse和火狐累

的tabMenu,来保存被隐藏的tabs,如下?

? ? ??

?????????尝试制作了一下,之前是用我自己的方法做了,后面被大佬指点了一下,完全改版了重新制作。目前效果如下:? ? ? ?

? ? ? ? ?

????????基本完成了tabs的宽度因窗口宽度的变化而显示tabs页面,并且被隐藏的页面与当前所显示的页面索引相关,意思是当前显示页面必定会在标签栏中间如下:

? ? ? ? 显示菜单的tab也是在有页面被隐藏的情况下才会显示,如下:

? ? ? ? 并且当tabMenu中的tab被点击时会在标签栏中插入该tab并将离它最远的tab隐藏至tabMenu中,如下:

?????????点击后:

? ? ? ? 被点击的tab为Tab0012,故将其添加回标签栏,并将Tab00234567隐藏于tabMenu中,并且拉伸窗口后其顺序不变.

? ? ? ? 本人只是初学,代码仍有许多待优化,进步的地方,仅供分享,非技术性展示.

主要代码结构:

def update(self):
        #计算展示的tab
        self.calcutab()

        #显示或隐藏tab菜单
        self.tabMenuState()

        #根据calcutab()展示tab
        self.updatetab()
        
        #根据calcutab()隐藏tab至tabMenu
        self.updatetabMenu()

主要代码部分:

1、计算显示的tab

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

                #更新数据
                self.r += 1
                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

                #更新数据
                self.l += 1
                
                print('调用删左边')
                print(self.tabs_show_status)

        #当tab宽度小于窗口宽度时
        elif self.barWidth+mw.tab_Rwidth < 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 :

                    if self.tabs_show_status[self.l-1] == 0 :
                        self.tabs_show_status[self.l-1] = 1
                    
                    elif self.tabs_show_status[self.l-1] == 1 :
                        self.tabs_show_status[self.l] = 1

                    #更新数据
                    self.l -= 1
                    
                    print('调用1左添加' )
                    print(self.tabs_show_status)

                elif self.l == 0 :
                    print('当前')
                    if self.tabs_show_status[len(self.tabs_page)-self.r] == 0 :
                        self.tabs_show_status[len(self.tabs_page)-self.r] = 1

                    elif self.tabs_show_status[len(self.tabs_page)-self.r] == 1 :
                        self.tabs_show_status[len(self.tabs_page)-self.r-1] = 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 :

                    if self.tabs_show_status[len(self.tabs_page)-self.r] == 0 :
                        self.tabs_show_status[len(self.tabs_page)-self.r] = 1

                    elif self.tabs_show_status[len(self.tabs_page)-self.r] == 1 :
                        self.tabs_show_status[len(self.tabs_page)-self.r-1] = 1
                    
                    #更新数据
                    self.r -= 1
                    print('调用2右添加' )
                    print(self.tabs_show_status)

                elif self.r == 0 :
                    
                    if self.tabs_show_status[self.l-1] == 0 :
                        self.tabs_show_status[self.l-1] = 1
                    
                    elif self.tabs_show_status[self.l-1] == 1 :
                        self.tabs_show_status[self.l] = 1

                    #更新数据
                    self.l -= 1
                    
                    print('调用2左添加' )
                    print(self.tabs_show_status)

2、标签页更新

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.insertTab(self.indexOf(self.tab_menu),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

3、更新被隐藏tab菜单

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)

? ? ? ? 其他部位为使代码能运行的补充与部分方法,完整代码如下,代码并非绝对还原eclipse,还有很多改善的地方,仅个人学习记录与分享.


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]


#重写QtabWidget
class TabWidget(QTabWidget):
    def __init__(self):
        super(TabWidget,self).__init__()
        
        self.tabbar = TabBar(self)
        self.setTabBar(self.tabbar)

        #工具数据
        self.tabs_show_status = {0:1,1:1,2:1,3:1,4:1,5:1,6:1,7:1,8:1,9:1}
        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.tab_menu = QWidget()
        self.menu = QMenu(self)
        self.menu_tab = QAction('菜单',self)
        self.menu.addAction(self.menu_tab)
        
        self.tabBarClicked.connect(self.onClicked)


    def onClicked(self, index):
        if self.indexOf(self.tab_menu) > -1  and mw.tabs.count()-1 == index:
            self.menu.exec_(QCursor.pos())
            
            
    def update(self):
        #计算展示的tab
        self.calcutab()

        #显示或隐藏tab菜单
        self.tabMenuState()

        #根据calcutab()展示tab
        self.updatetab()
        
        #根据calcutab()隐藏tab至tabMenu
        self.updatetabMenu()


    def tabMenuState(self):

        if self.indexOf(self.tab_menu) == -1 and self.l+self.r > 0:
            self.addTab(self.tab_menu, "<<")
            
            self.barWidth += self.tabbar.tabSizeHint(self.indexOf(self.tab_menu)).width()

            print('调用menu1')
            print(self.l)
            print(self.r)
            

        elif self.indexOf(self.tab_menu) > -1 and self.l+self.r == 0:
            self.barWidth -= self.tabbar.tabSizeHint(self.indexOf(self.tab_menu)).width()
            self.removeTab(self.indexOf(self.tab_menu))
            #self.page -= 1
            print('调用menu2')


    #计算需要展示的页面
    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

                #更新数据
                self.r += 1
                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

                #更新数据
                self.l += 1
                
                print('调用删左边')
                print(self.tabs_show_status)

        #当tab宽度小于窗口宽度时
        elif self.barWidth+mw.tab_Rwidth < 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 :

                    if self.tabs_show_status[self.l-1] == 0 :
                        self.tabs_show_status[self.l-1] = 1
                    
                    elif self.tabs_show_status[self.l-1] == 1 :
                        self.tabs_show_status[self.l] = 1

                    #更新数据
                    self.l -= 1
                    
                    print('调用1左添加' )
                    print(self.tabs_show_status)

                elif self.l == 0 :
                    print('当前')
                    if self.tabs_show_status[len(self.tabs_page)-self.r] == 0 :
                        self.tabs_show_status[len(self.tabs_page)-self.r] = 1

                    elif self.tabs_show_status[len(self.tabs_page)-self.r] == 1 :
                        self.tabs_show_status[len(self.tabs_page)-self.r-1] = 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 :

                    if self.tabs_show_status[len(self.tabs_page)-self.r] == 0 :
                        self.tabs_show_status[len(self.tabs_page)-self.r] = 1

                    elif self.tabs_show_status[len(self.tabs_page)-self.r] == 1 :
                        self.tabs_show_status[len(self.tabs_page)-self.r-1] = 1
                    
                    #更新数据
                    self.r -= 1
                    print('调用2右添加' )
                    print(self.tabs_show_status)

                elif self.r == 0 :
                    
                    if self.tabs_show_status[self.l-1] == 0 :
                        self.tabs_show_status[self.l-1] = 1
                    
                    elif self.tabs_show_status[self.l-1] == 1 :
                        self.tabs_show_status[self.l] = 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.insertTab(self.indexOf(self.tab_menu),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
                
        
    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
            
            index=0
            while self.tabs_show_status[index] == 0 :
                index += 1
            self.tabs_show_status[index] = 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
            self.tabs_show_status[index] = 0

            self.l -= 1
            self.r += 1

        #根据calcutab()展示tab
        self.updatetab()
        
        #根据calcutab()隐藏tab至tabMenu
        self.updatetabMenu()
        print(self.tabs_show_status)

 
class TabBar(QTabBar):
    def __init__(self,parent,*args,**kwargs):
        QTabBar.__init__(self,parent,*args,**kwargs)

        self.tabMoved.connect(self.tabMovedCode)

    def tabMovedCode(self,x,y,):

        mw.tabs.tabs_page[999] = mw.tabs.tabs_page[y]
        mw.tabs.tabs_page[y] = mw.tabs.tabs_page[x]
        mw.tabs.tabs_page[x] = mw.tabs.tabs_page[999]
        del mw.tabs.tabs_page[999]

        char = mw.tabs.tabs_text[x]
        mw.tabs.tabs_text[x] = mw.tabs.tabs_text[y]
        mw.tabs.tabs_text[y] = char
    

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()
        self.btn = QPushButton()
        # Alllayout = QHBoxLayout()
        Alllayout = QVBoxLayout()
        # 设置控件无边界 无边框
        Alllayout.setSpacing(0)
        Alllayout.setContentsMargins(0, 0, 0, 0)
        AllWidget.setLayout(Alllayout)
        self.tabs = TabWidget()
        
        self.tabs.setMovable(True)
        
        self.tab_menu = QWidget()

        for i in range(0,10):
            
            self.tabs.tabs_page[i] = QWidget()
            self.x += str(i)
            self.tabs.addTab(self.tabs.tabs_page[i], "Tab"+self.x)
            self.tabs.tabs_text.append(self.tabs.tabText(i))
            self.tabs.tabs_width[i] = self.tabs.tabbar.tabSizeHint(i).width()

            #创建菜单
            self.tabs.tabs_menu_item[i] = QAction(self.tabs.tabText(i),self)
            self.tabs.menu.addAction(self.tabs.tabs_menu_item[i])
            self.tabs.tabs_menu_item[i].triggered.connect(partial(self.tabs.menuJump,i))
            
            #窗口宽度
            self.tabs.barWidth += self.tabs.tabs_width[i]

            self.tabs.page += 1

            #最右与最左tab的宽度
            self.tab_Rwidth = self.tabs.tabbar.tabSizeHint(self.tabs.page).width()
            self.tab_Lwidth = self.tabs.tabbar.tabSizeHint(0).width()
            
            print(self.tabs.tabs_width) 
            
        self.setCentralWidget(self.tabs)
        self.resize(2000, 1000)
        Alllayout.addWidget(self.tabs)
        self.setCentralWidget(AllWidget)

    def resizeEvent(self, event):
        self.w = event.size().width()
        self.h = event.size().height()

        self.tabs.update()
        

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2021-09-01 12:08:05  更:2021-09-01 12:09:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/22 23:38:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计