PyQt實例:設計有摺疊效果的左側選項卡,且點擊不同選項卡能進行不同界面的切換

聲明:本文僅供學習用,旨在分享
首先先來看下效果圖:
在這裏插入圖片描述
要實現上面的頁面切換效果,除了QListWidget外,還需要用到一個控件QStackedWidget,叫做堆載窗口控件,QStackedWidget控件與QTabWidget類似,可以有效的顯示窗口的控件。以下是代碼:

# -*- coding: utf-8 -*-
from random import randint
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

app_name='小程序'
top=['主菜單1','主菜單2','主菜單3']
tab=['子菜單1', '子菜單2', '子菜單3','子菜單4','子菜單5']

class LeftWidget(QWidget):
    update_ = pyqtSignal(str)
    def __init__(self, item,factor,parent=None):
        super(LeftWidget, self).__init__(parent)
        self.item = item
        layout = QFormLayout(self)
        self.button1 = QPushButton(factor[0])
        layout.addRow(self.button1)
        self.button1.clicked.connect(self.onClick)
        if len(factor) >=3:
            self.button2 = QPushButton(factor[1])
            self.button3 = QPushButton(factor[2])
            layout.addRow(self.button2)
            layout.addRow(self.button3)
            self.button2.clicked.connect(self.onClick)
            self.button3.clicked.connect(self.onClick)
            if len(factor)>=4:
                self.button4 = QPushButton(factor[3])
                layout.addRow(self.button4)
                self.button4.clicked.connect(self.onClick)

    def onClick(self):
        txt = self.sender().text()#獲取發送信號的控件文本
        self.update_.emit(txt)

    def resizeEvent(self, event):
        # 解決item的高度問題
        super(LeftWidget, self).resizeEvent(event)
        self.item.setSizeHint(QSize(self.minimumWidth(), self.height()))

class TabButton(QPushButton):
    # 按鈕作爲開關
    def __init__(self, item,name,parent=None):
        super(TabButton, self).__init__(parent)
        self.item = item
        self.setCheckable(True)  # 設置可選中
        self.setText(name)

    def resizeEvent(self, event):
        # 解決item的高度問題
        super(TabButton, self).resizeEvent(event)
        self.item.setSizeHint(QSize(self.minimumWidth(), self.height()))


class LeftWindow(QListWidget):
    def __init__(self, *args, **kwargs):
        super(LeftWindow, self).__init__(*args, **kwargs)
        warn = QListWidgetItem(self)
        warn_btn = TabButton(warn,top[0])
        self.setItemWidget(warn, warn_btn)
        # 被摺疊控件
        warn_item = QListWidgetItem(self)
        # 通過按鈕的選中來隱藏下面的item
        warn_btn.toggled.connect(warn_item.setHidden)
        self.warn_widget=LeftWidget(warn_item, tab[:3])
        self.setItemWidget(warn_item,self.warn_widget)
        warn_item.setHidden(True)#默認不展開

        device= QListWidgetItem(self)
        device_btn = TabButton(device, top[1])
        self.setItemWidget(device, device_btn)
        # 被摺疊控件
        device_item = QListWidgetItem(self)
        # 通過按鈕的選中來隱藏下面的item
        device_btn.toggled.connect(device_item.setHidden)
        self.device_widget=LeftWidget(device_item, [tab[3]])
        self.setItemWidget(device_item, self.device_widget)
        device_item.setHidden(True)  # 默認不展開

        system = QListWidgetItem(self)
        system_btn = TabButton(system, top[2])
        self.setItemWidget(system, system_btn)
        # 被摺疊控件
        system_item = QListWidgetItem(self)
        # 通過按鈕的選中來隱藏下面的item
        system_btn.toggled.connect(system_item.setHidden)
        self.system_widget=LeftWidget(system_item, [tab[4]])
        self.setItemWidget(system_item,self.system_widget)
        system_item.setHidden(True)  # 默認不展開


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUI()

    def setupUI(self):
        self.available_geometry = QDesktopWidget().availableGeometry()
        init_width = self.available_geometry.width() * 0.85
        init_height = self.available_geometry.height() * 0.85
        self.setWindowTitle(app_name)
        self.resize(init_width, init_height)
        # 實例化狀態欄,設置狀態欄
        self.statusBar = QStatusBar()
        self.setStatusBar(self.statusBar)
        ###### 創建界面 ######
        self.centralwidget = QWidget()
        self.setCentralWidget(self.centralwidget)
        self.mainLayout = QHBoxLayout(self.centralwidget)#全局橫向

        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.setSpacing(0)  # 去除控件間的間隙
        #################
        self.listWidget = LeftWindow()  # 左側列表
        self.listWidget.setMaximumWidth(150)
        self.listWidget.setMinimumWidth(150)
        # 去掉邊框
        self.listWidget.setFrameShape(QListWidget.NoFrame)
        # 隱藏滾動條
        self.listWidget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.listWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.StackDataDisplay = QStackedWidget()  # 右側層疊窗口
        # 再模擬幾個右側的頁面
        for i in range(5):
            label = QLabel('這是頁面 %d' % i, self)
            label.setAlignment(Qt.AlignCenter)
            # 此處加了一個margin邊距(方便區分QStackedWidget和QLabel的顏色)
            label.setStyleSheet('background: rgb(%d, %d, %d);margin: 50px;' % (
                randint(0, 255), randint(0, 255), randint(0, 255)))
            self.StackDataDisplay.addWidget(label)
        self.listWidget.warn_widget.update_.connect(self.update_tab)
        self.listWidget.device_widget.update_.connect(self.update_tab)
        self.listWidget.system_widget.update_.connect(self.update_tab)
        ###################
        self.mainLayout.addWidget(self.listWidget)
        self.mainLayout.addWidget(self.StackDataDisplay)

    def update_tab(self,text):
        self.StackDataDisplay.setCurrentIndex(tab.index(text))#根據文本設置不同的頁面

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章