问题的提出
在GUI应用中,常常会遇到这样的问题,比如显示一幅大的图像,但显示区域有限,不能完整地显示整个图像,或者能展示界面的区域有限,但是界面中需要展现的控件、内容却很多,在限定的区域内无法全部展示。这个时候我们就需要区域是可以水平和(或)垂直方向可以滚动,以实现对整个图像或者所有控件的浏览。在PyQt中,提供滚动区控件QScrollArea来实现这个功能。
QScrollArea简介
QScrollArea滚动区域控件类提供了关于另一个窗口的滚动的视图,一个滚动区域通常用来显示一个子窗口。如果子窗口中的内容超过了显示窗口的大小,这时候QSrollArea就会自动提供滚动条,通过操作滚动条,用户就可以浏览整个图像或者是操控窗口中的所有控件。
QSrollArea可以给任何QWidget控件添加滚动条。
QScrollArea常用方法有:
- setWidget(): 设置控件为QScrollArea的子控件;
- takeWidget():删除QScrollArea的子控件;
- widget(): 返回QScrollArea的子控件;
- setWidgetResizable(): 设置为true,则滚动区域部件将自动调整,以避免可以不显示的滚动条,或者利用额外的空间;
- widgetResizable(): 获得区域里的控件是否自动可调的设置;
- ensureVisible(): 确保一定区域可见,必要时滚动;
- ensureWidgetVisible(): 确保指定的控件widget可见,必要时滚动;
QScrollArea类继承关系:
测试QScrollArea
创建文件qscrollarea.py, 水平设置两个滚动区域,分别演示图像滚动显示和控件滚动。完整代码如下:
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())
运行结果如下图:
测试QScrollArea
本文知识点
- 使用滚动区域浏览较大的图像;
- 使用QSpliter 连调整两个区域的相对大小;
- 使用Qalette设置控件的背景颜色。