实战PyQt5: 049-滚动区域控件QScrollArea

问题的提出

在GUI应用中,常常会遇到这样的问题,比如显示一幅大的图像,但显示区域有限,不能完整地显示整个图像,或者能展示界面的区域有限,但是界面中需要展现的控件、内容却很多,在限定的区域内无法全部展示。这个时候我们就需要区域是可以水平和(或)垂直方向可以滚动,以实现对整个图像或者所有控件的浏览。在PyQt中,提供滚动区控件QScrollArea来实现这个功能。

QScrollArea简介

QScrollArea滚动区域控件类提供了关于另一个窗口的滚动的视图,一个滚动区域通常用来显示一个子窗口。如果子窗口中的内容超过了显示窗口的大小,这时候QSrollArea就会自动提供滚动条,通过操作滚动条,用户就可以浏览整个图像或者是操控窗口中的所有控件。

QSrollArea可以给任何QWidget控件添加滚动条。

QScrollArea常用方法有:

  • setWidget(): 设置控件为QScrollArea的子控件;
  • takeWidget():删除QScrollArea的子控件;
  • widget(): 返回QScrollArea的子控件;
  • setWidgetResizable(): 设置为true,则滚动区域部件将自动调整,以避免可以不显示的滚动条,或者利用额外的空间;
  • widgetResizable(): 获得区域里的控件是否自动可调的设置;
  • ensureVisible(): 确保一定区域可见,必要时滚动;
  • ensureWidgetVisible(): 确保指定的控件widget可见,必要时滚动;

QScrollArea类继承关系:

实战PyQt5: 049-滚动区域控件QScrollArea

测试QScrollArea

创建文件qscrollarea.py, 水平设置两个滚动区域,分别演示图像滚动显示和控件滚动。完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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('实战PyQt5: QScrollArea Demo!')      
        # 设置窗口大小
        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())

运行结果如下图:

实战PyQt5: 049-滚动区域控件QScrollArea

测试QScrollArea

本文知识点

  • 使用滚动区域浏览较大的图像;
  • 使用QSpliter 连调整两个区域的相对大小;
  • 使用Qalette设置控件的背景颜色。

前一篇: 实战PyQt5: 048-工具箱控件QToolBox