Qt Designer基本控件介绍——Containers(容器)

2021-07-12 14:16:22 浏览数 (1)

  • Group Box : 组合框。就是将组合框内的控件标识为一组控件来使用,即一次只能选择其中的一个控件:如性别选择,当选择男时,女不被选择;当选择女时男不被选择

clicked(): 点击QGroupBox控件时,发射该信号;

toggled(): 当QGroupBox的状态发生了改变时,发射该信息

代码语言:javascript复制
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QWidget, QGroupBox, QRadioButton, QLabel, QHBoxLayout, QVBoxLayout


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.groupbox_1 = QGroupBox('On and Off', self)                       # 1
        self.groupbox_2 = QGroupBox('Change Color', self)

        self.red = QRadioButton('Red', self)                                  # 2
        self.blue = QRadioButton('Blue', self)
        self.green = QRadioButton('Green', self)
        self.yellow = QRadioButton('Yellow', self)
        self.color_list = [self.red, self.blue, self.green, self.yellow]

        self.on = QRadioButton('On', self)                                    # 3
        self.off = QRadioButton('Off', self)

        self.pic_label = QLabel(self)                                         # 4

        self.h1_layout = QHBoxLayout()
        self.h2_layout = QHBoxLayout()
        self.h3_layout = QHBoxLayout()
        self.all_v_layout = QVBoxLayout()

        self.layout_init()
        self.radiobutton_init()
        self.label_init()

    def layout_init(self):
        self.h1_layout.addWidget(self.on)
        self.h1_layout.addWidget(self.off)
        self.groupbox_1.setLayout(self.h1_layout)

        self.h2_layout.addWidget(self.red)
        self.h2_layout.addWidget(self.blue)
        self.h2_layout.addWidget(self.green)
        self.h2_layout.addWidget(self.yellow)
        self.groupbox_2.setLayout(self.h2_layout)

        self.h3_layout.addWidget(self.groupbox_1)
        self.h3_layout.addWidget(self.groupbox_2)

        self.all_v_layout.addWidget(self.pic_label)
        self.all_v_layout.addLayout(self.h3_layout)

        self.setLayout(self.all_v_layout)

    def radiobutton_init(self):                                              
        self.yellow.setChecked(True)                                         # 5
        for btn in self.color_list:
            btn.clicked.connect(self.change_color_func)

        self.off.setChecked(True)                                            # 6
        self.off.toggled.connect(self.on_and_off_func)

    def label_init(self):                                                    # 7
        self.pic_label.setPixmap(QPixmap('images/Off.png'))
        self.pic_label.setAlignment(Qt.AlignCenter)

    def change_color_func(self):
        if self.on.isChecked():
            path = 'images/{}.png'.format([btn.text() for btn in self.color_list if btn.isChecked()][0])
            self.pic_label.setPixmap(QPixmap(path))

    def on_and_off_func(self):
        if self.on.isChecked():
            path = 'images/{}.png'.format([btn.text() for btn in self.color_list if btn.isChecked()][0])
            self.pic_label.setPixmap(QPixmap(path))
        else:
            self.pic_label.setPixmap(QPixmap('images/Off.png'))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())
左边选择”On“,右边选择”Red“的结果图左边选择”On“,右边选择”Red“的结果图
左边选择”On“,右边选择”Blue“的结果图左边选择”On“,右边选择”Blue“的结果图
左边选择”Off“的结果图左边选择”Off“的结果图
  • Scroll Area :含滚动条的区域。QScrollArea滚动区域控件类,提供了关于另一个窗口的滚动的视图,一个滚动区域通常用来显示一个子窗口。如果子窗口中的内容超过了显示窗口的大小,这时候QSrollArea就会自动提供滚动条,通过操作滚动条,用户就可以浏览整个图像或者是操控窗口中的所有控件。

setWidget(): 设置控件为QScrollArea的子控件;

takeWidget():删除QScrollArea的子控件;

widget(): 返回QScrollArea的子控件;

setWidgetResizable(): 设置为true,则滚动区域部件将自动调整,以避免可以不显示的滚动条,或者利用额外的空间;

widgetResizable(): 获得区域里的控件是否自动可调的设置;

ensureVisible(): 确保一定区域可见,必要时滚动;

ensureWidgetVisible(): 确保指定的控件widget可见,必要时滚动;

代码语言:javascript复制
import sys, os
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import (QApplication, QWidget, QSplitter, QVBoxLayout,
                             QGroupBox, QScrollArea, QRadioButton, QCheckBox,
                             QLabel)
from PyQt5.QtGui import QPixmap, QPalette
from PyQt5.QtCore import Qt


class DemoScrollArea(QWidget):
    def __init__(self, parent=None):
        super(DemoScrollArea, self).__init__(parent)

        # 设置窗口标题
        self.setWindowTitle('练习:ScrollArea')
        # 设置窗口大小
        self.resize(480, 360)

        self.initUi()

    def initUi(self):
        mainLayout = QVBoxLayout(self)

        hSplitter = QSplitter(Qt.Horizontal)

        saLeft = QScrollArea(self)
        disp_img = QLabel(self)
        disp_img.setPixmap(QPixmap(os.path.dirname(__file__)   '/trp.jpg')) 
        saLeft.setBackgroundRole(QPalette.Dark)
        saLeft.setWidget(disp_img)

        saRight = QScrollArea(self)
        # 滚动区域的Widget
        scrollAreaWidgetContents = QWidget()
        vLayout = QVBoxLayout(scrollAreaWidgetContents)
        vLayout.addWidget(self.createFirstExclusiveGroup())
        vLayout.addWidget(self.createSecondExclusiveGroup())
        vLayout.addWidget(self.createNonExclusiveGroup())
        scrollAreaWidgetContents.setLayout(vLayout)
        saRight.setWidget(scrollAreaWidgetContents)

        hSplitter.addWidget(saLeft)
        hSplitter.addWidget(saRight)
        mainLayout.addWidget(hSplitter)
        self.setLayout(mainLayout)

    def createFirstExclusiveGroup(self):
        groupBox = QGroupBox('Exclusive Radio Buttons', self)

        radio1 = QRadioButton('&Radio Button 1', self)
        radio1.setChecked(True)
        radio2 = QRadioButton('R&adio button 2', self)
        radio3 = QRadioButton('Ra&dio button 3', self)

        vLayout = QVBoxLayout(groupBox)
        vLayout.addWidget(radio1)
        vLayout.addWidget(radio2)
        vLayout.addWidget(radio3)
        vLayout.addStretch(1)

        groupBox.setLayout(vLayout)

        return groupBox

    def createSecondExclusiveGroup(self):
        groupBox = QGroupBox('E&xclusive Radio Buttons', self)
        groupBox.setCheckable(True)
        groupBox.setChecked(True)

        radio1 = QRadioButton('Rad&io button1', self)
        radio1.setChecked(True)
        radio2 = QRadioButton('Radi&o button2', self)
        radio3 = QRadioButton('Radio &button3', self)
        chkBox = QCheckBox('Ind&ependent checkbox', self)

        vLayout = QVBoxLayout(groupBox)
        vLayout.addWidget(radio1)
        vLayout.addWidget(radio2)
        vLayout.addWidget(radio3)
        vLayout.addWidget(chkBox)
        vLayout.addStretch(1)

        groupBox.setLayout(vLayout)

        return groupBox

    def createNonExclusiveGroup(self):
        groupBox = QGroupBox('No-Exclusive Checkboxes', self)
        groupBox.setFlat(True)

        chBox1 = QCheckBox('&Checkbox 1')
        chBox2 = QCheckBox('C&heckbox 2')
        chBox2.setChecked(True)
        tristateBox = QCheckBox('Tri-&state buttton')
        tristateBox.setTristate(True)
        tristateBox.setCheckState(Qt.PartiallyChecked)

        vLayout = QVBoxLayout(groupBox)
        vLayout.addWidget(chBox1)
        vLayout.addWidget(chBox2)
        vLayout.addWidget(tristateBox)
        vLayout.addStretch(1)

        groupBox.setLayout(vLayout)

        return groupBox


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = DemoScrollArea()
    window.show()
    sys.exit(app.exec())
运行结果运行结果
  • Tool Box :工具箱。可以理解为,工具箱有很多抽屉,每次只能打开一个,抽屉里可以放很各种各样的东西,例如QQ的好友分组,每个分组下有不同数目的联系人。

点击不同抽屉时,会触发currentChanged信号

代码语言:javascript复制
import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QToolBox, QGroupBox, QToolButton, QVBoxLayout


class Demo(QToolBox):                                           # 1
    def __init__(self):
        super(Demo, self).__init__()
        self.groupbox_1 = QGroupBox(self)                       # 2
        self.groupbox_2 = QGroupBox(self)
        self.groupbox_3 = QGroupBox(self)

        self.toolbtn_f1 = QToolButton(self)                     # 3
        self.toolbtn_f2 = QToolButton(self)
        self.toolbtn_f3 = QToolButton(self)
        self.toolbtn_m1 = QToolButton(self)
        self.toolbtn_m2 = QToolButton(self)
        self.toolbtn_m3 = QToolButton(self)

        self.v1_layout = QVBoxLayout()
        self.v2_layout = QVBoxLayout()
        self.v3_layout = QVBoxLayout()

        self.addItem(self.groupbox_1, 'Couple One')             # 4
        self.addItem(self.groupbox_2, 'Couple Two')
        self.addItem(self.groupbox_3, 'Couple Three')
        self.currentChanged.connect(self.print_index_func)      # 5

        self.layout_init()
        self.groupbox_init()
        self.toolbtn_init()

    def layout_init(self):
        self.v1_layout.addWidget(self.toolbtn_f1)
        self.v1_layout.addWidget(self.toolbtn_m1)
        self.v2_layout.addWidget(self.toolbtn_f2)
        self.v2_layout.addWidget(self.toolbtn_m2)
        self.v3_layout.addWidget(self.toolbtn_f3)
        self.v3_layout.addWidget(self.toolbtn_m3)

    def groupbox_init(self):                                    # 6
        self.groupbox_1.setFlat(True)
        self.groupbox_2.setFlat(True)
        self.groupbox_3.setFlat(True)
        self.groupbox_1.setLayout(self.v1_layout)
        self.groupbox_2.setLayout(self.v2_layout)
        self.groupbox_3.setLayout(self.v3_layout)

    def toolbtn_init(self):                                     # 7 
        # 注意路径为'images/xxx.ico,所以需要在项目中新建一个images文件夹来存放这些图片文件    
        self.toolbtn_f1.setIcon(QIcon('images/gg1.ico'))
        self.toolbtn_f2.setIcon(QIcon('images/gg2.ico'))
        self.toolbtn_f3.setIcon(QIcon('images/gg3.ico'))
        self.toolbtn_m1.setIcon(QIcon('images/mm1.ico'))
        self.toolbtn_m2.setIcon(QIcon('images/mm2.ico'))
        self.toolbtn_m3.setIcon(QIcon('images/mm3.ico'))

    def print_index_func(self):
        couple_dict = {
            0: 'Couple One',
            1: 'Couple Two',
            2: 'Couple Three'
        }
        sentence = 'You are looking at {}.'.format(couple_dict.get(self.currentIndex()))
        # 通过currentIndex()方法可以获取到当前所点击的抽屉序号,序号从0开始。
        # 这里通过字典来获取相应的抽屉名称,然后将其打印出来
        print(sentence)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())
运行结果(具体显示什么图片可以自己修改)运行结果(具体显示什么图片可以自己修改)
每次点击不同的抽屉,控制台都会输出相应的抽屉名每次点击不同的抽屉,控制台都会输出相应的抽屉名
  • Tab Widget :多页面切换。可以实现在同一区域中自由切换不同页面的内容,该控件是一个容器类控件,并提供友好的页面切换方式。

常用方法:

addTab(): 添加一个标签;

insertTab(): 在指定位置插入一个标签;

removeTab(): 删除指定索引的标签;

setTabText(): 设置指定索引标签的文本信息;

tabText(): 获得指定索引标签的文本信息;

setTabIcon(): 设置指定索引标签的图标;

tabIcon(): 获得指定索引标签的图标;

currentWidget(): 获得当前活动标签的部件;

widget(): 获得指定标签索引的部件;

indexOf(): 获得指定部件的标签索引;

count(): 总标签数;

setTabPosition(): 设置标签的显示位置,值为(北:QTabWidget.North, 南:QTabWidget.South, 西:QTabWidget.West, 东:QTabWidget.East);

setTabShape(): 设置标签的形状, 值为:(四边形:QTabWidget.Rounded, 三角形:QTabWidget.Triangular)。


信号:

currentChanged: 当前标签页发生改变后,发射该信号;

tabCloseRequested: 标签页关闭请求时,发射该信号;

tabBarClicked: 单击了标签条,发射该信号;

tabBarDoubleClicked: 双击了标签条,发射该信号。

代码语言:javascript复制
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget,
                             QTabWidget, QMenuBar, QMenu, QAction,
                             QActionGroup, QVBoxLayout, QLabel)

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

        # 设置窗口标题
        self.setWindowTitle('练习:QTabWidget')
        # 设置窗口大小
        self.resize(480, 360)

        self.initUi()

    def initUi(self):
        self.initMenu()

        self.tw = QTabWidget(self)
        self.tw.addTab(self.createWidget(0), '常规')
        self.tw.addTab(self.createWidget(1), '快捷方式')
        self.tw.addTab(self.createWidget(2), '兼容性')
        self.tw.addTab(self.createWidget(3), '安全')
        self.tw.addTab(self.createWidget(4), '详细信息')
        self.tw.addTab(self.createWidget(5), '以前的版本')

        self.setCentralWidget(self.tw)

    def initMenu(self):
        menuBar = self.menuBar()
        # 添加一个菜单项,在菜单项下课添加子菜单项
        fileMenu = menuBar.addMenu('文件')
        aExit = QAction('Exit', self)
        aExit.triggered.connect(self.close)
        fileMenu.addAction(aExit)

        # 标签条位置控制
        posMenu = menuBar.addMenu('标签条位置')

        aNorth = QAction('上方', self)
        aNorth.setCheckable(True)
        aNorth.setChecked(True)
        aNorth.triggered.connect(lambda: self.changeTabPos(0))
        aSouth = QAction('下方', self)
        aSouth.setCheckable(True)
        aSouth.triggered.connect(lambda: self.changeTabPos(1))
        aWest = QAction('左边', self)
        aWest.setCheckable(True)
        aWest.triggered.connect(lambda: self.changeTabPos(2))
        aEast = QAction('右边', self)
        aEast.setCheckable(True)
        aEast.triggered.connect(lambda: self.changeTabPos(3))

        posGroup = QActionGroup(self)
        posGroup.addAction(aNorth)
        posGroup.addAction(aSouth)
        posGroup.addAction(aWest)
        posGroup.addAction(aEast)

        posMenu.addAction(aNorth)
        posMenu.addAction(aSouth)
        posMenu.addAction(aWest)
        posMenu.addAction(aEast)

        # 标签条形状
        shapeMenu = menuBar.addMenu('标签条形状')
        aRounded = QAction('圆角矩形', self)
        aRounded.setCheckable(True)
        aRounded.setChecked(True)
        aRounded.triggered.connect(lambda: self.changeTabShape(0))
        aTriangular = QAction('三角形', self)
        aTriangular.setCheckable(True)
        aTriangular.triggered.connect(lambda: self.changeTabShape(1))

        shapeGroup = QActionGroup(self)
        shapeGroup.addAction(aRounded)
        shapeGroup.addAction(aTriangular)

        shapeMenu.addAction(aRounded)
        shapeMenu.addAction(aTriangular)

    def changeTabPos(self, index):
        switcher = {
            0: QTabWidget.North,
            1: QTabWidget.South,
            2: QTabWidget.West,
            3: QTabWidget.East
        }
        self.tw.setTabPosition(switcher.get(index))

    def changeTabShape(self, index):
        if index == 0:
            self.tw.setTabShape(QTabWidget.Rounded)
        else:
            self.tw.setTabShape(QTabWidget.Triangular)

    def createWidget(self, index):
        wid = QWidget()
        layout = QVBoxLayout(wid)
        label = QLabel(wid)
        label.setAlignment(Qt.AlignCenter)
        label.setFont(QFont(self.font().family(), 36))
        label.setText("选项卡 {}".format(index   1))

        layout.addWidget(label)
        wid.setLayout(layout)
        return wid


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = DemoTabWidget()
    window.show()
    sys.exit(app.exec())
运行结果运行结果
  • Stacked Widget :层叠窗口(堆栈窗口),多界面切换。可以填充一些小控件,但是同一时间只有一个小控件可以显示。

QStackedWidget控件不能在页面之间进行切换,它与当前选中的QListWidget控件中的选项进行连接

currentRowChanged信号

代码语言:javascript复制
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class StackedExample(QWidget):
    def __init__(self):
        super(StackedExample, self).__init__()
        #设置窗口初始位置和大小
        self.setGeometry(300,50,10,10)
        self.setWindowTitle('练习: StackedWidget')

        #创建列表窗口,添加条目
        self.leftlist=QListWidget()
        self.leftlist.insertItem(0,'联系方式')
        self.leftlist.insertItem(1,'个人信息')
        self.leftlist.insertItem(2,'教育程度')

        #创建三个小控件
        self.stack1=QWidget()
        self.stack2=QWidget()
        self.stack3=QWidget()

        self.stack1UI()
        self.stack2UI()
        self.stack3UI()

        #在QStackedWidget对象中填充了三个子控件
        self.stack=QStackedWidget(self)

        self.stack.addWidget(self.stack1)
        self.stack.addWidget(self.stack2)
        self.stack.addWidget(self.stack3)

        #水平布局,添加部件到布局中
        HBox=QHBoxLayout()
        HBox.addWidget(self.leftlist)
        HBox.addWidget(self.stack)

        self.setLayout(HBox)

        self.leftlist.currentRowChanged.connect(self.display)
    def stack1UI(self):
        layout=QFormLayout()
        layout.addRow('姓名',QLineEdit())
        layout.addRow('地址',QLineEdit())
        self.stack1.setLayout(layout)

    def stack2UI(self):
        # zhu表单布局,次水平布局
        layout = QFormLayout()
        sex = QHBoxLayout()

        # 水平布局添加单选按钮
        sex.addWidget(QRadioButton('男'))
        sex.addWidget(QRadioButton('女'))

        # 表单布局添加控件
        layout.addRow(QLabel('性别'), sex)
        layout.addRow('生日', QLineEdit())

        self.stack2.setLayout(layout)

    def stack3UI(self):
        # 水平布局
        layout = QHBoxLayout()

        # 添加控件到布局中
        layout.addWidget(QLabel('科目'))
        layout.addWidget(QCheckBox('物理'))
        layout.addWidget(QCheckBox('高数'))

        self.stack3.setLayout(layout)
    def display(self,i):
        #设置当前可见的选项卡的索引
        self.stack.setCurrentIndex(i)
if __name__ == '__main__':
    app=QApplication(sys.argv)
    demo=StackedExample()
    demo.show()
    sys.exit(app.exec_())
运行结果运行结果
  • Frame :框架,控制一些边框的样式,凸起,凹下,阴影等。

setLineWidth(int width):设置外线宽度

midLineWidth():设置中线宽度

setFrameShape(QFrame.Shape):设置边框形状

setFrameShadow(QFrame.Shadow):设置边框阴影

setFrameStyle(int style):设置边框样式

setFrameRect(QRect):设置边框矩形

QFrame 没有特有信号,所有信号继承自父类

官方文档给出的样式表(右侧的两列名字,为setFrameStyle的参数)官方文档给出的样式表(右侧的两列名字,为setFrameStyle的参数)
代码语言:javascript复制
#以右侧的WinPanel和Raised为例:
from PyQt5.Qt import *
import sys

app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("QFrame")
w.resize(300, 300)

fra = QFrame(w)
fra.resize(30,20)
fra.setStyleSheet("background-color:skyblue")

fra.setLineWidth(3)                              #设置外线宽度
fra.setMidLineWidth(3)                           #设置中线宽度
fra.setFrameStyle(QFrame.WinPanel|QFrame.Raised) #根据上表,选择参数写入

w.show()

if __name__ == '__main__':
    sys.exit(app.exec_())
运行结果运行结果
  • Widget :组件,主窗体容器。
  • MDI Area :可以同时显示多个文档的区域。

subWindowActivated: 特定子窗口被激活时发射该信号

详细介绍和示例可看博客”实战PyQt5: 051-多窗口文档控件QMdiArea“

  • Dock Widget :浮动窗口。它是放置在QMainWindow中的中央窗口小部件周围的停靠窗口小部件区域中的次要窗口。QDockWidget由一个标题栏和内容区域组成。标题栏显示浮动窗口小部件窗口标题,浮动按钮和关闭按钮。

featuresChanged: 停靠窗口的特性发生了改变时发射该信号;

topLevelChanged: 停靠窗口的浮动属性发生了改变时发射该信号;

allowedAreasChanged: 停靠窗口的允许停靠区域发生了改变时发射该信号;

visibilityChanged: 停靠窗口的可视属性(显示/隐藏)发生改变时发射该信号;

dockLocationChanged: 停靠窗口的位置发生了改变时发射该信号。

详细介绍可看博客”实战PyQt5: 052-停靠窗口控件QDockWidget“

0 人点赞