【转】PyQt4 精彩实例分析 实例 20 窗体的淡入淡出效果
本实例实现一个窗体淡入淡出效果的例子,当窗体进行页面切换时,原页面的消失和新页面的显现并不是瞬间
切换的,而是逐渐消隐和逐渐显现的过程。
本实例实现淡入淡出效果的基本原理可由下图描述。

当对话框由页面 1 切换至页面 2 时,在响应页面切换命令的同时,新建一个 FaderWidget 窗体,此窗体是一
个与对话框等尺寸的空白窗体,此窗体由不透明逐渐变为完全透明,即实现页面的淡入淡出效果。
本实例将实例 17 的实现改造成淡入淡出效果,主对话框由一个列表框 QListWidget 和一个堆栈窗体
QStackedWidget 组成,列表框中列出了可显示的 3 个页面名称:“基本资料”,“联系方式”和“详细资
料”,如下图所示。堆栈窗体中包含了对应的 3 个页面。

具体实现代码如下:
1 # -*- coding: utf-8 -*- 2 3 from PyQt4.QtGui import * 4 from PyQt4.QtCore import * 5 import sys 6 7 QTextCodec.setCodecForTr(QTextCodec.codecForName("utf8")) 8 9 class StockDialog(QDialog): 10 def __init__(self, parent=None): 11 super(StockDialog, self).__init__(parent) 12 self.setWindowTitle(self.tr("综合布局实例")) 13 mainSplitter = QSplitter(Qt.Horizontal) 14 mainSplitter.setOpaqueResize(True) 15 self.listWidget = QListWidget(mainSplitter) 16 self.listWidget.insertItem(0, self.tr("个人基本资料")) 17 self.listWidget.insertItem(1, self.tr("联系方式")) 18 self.listWidget.insertItem(2, self.tr("详细信息")) 19 frame = QFrame(mainSplitter) 20 self.stack = QStackedWidget() 21 self.stack.setFrameStyle(QFrame.Panel|QFrame.Raised) 22 baseInfo = BaseInfo() 23 contact = Contact() 24 detail = Detail() 25 self.stack.addWidget(baseInfo) 26 self.stack.addWidget(contact) 27 self.stack.addWidget(detail) 28 amendPushButton = QPushButton(self.tr("修改")) 29 closePushButton = QPushButton(self.tr("关闭")) 30 buttonLayout = QHBoxLayout() 31 buttonLayout.addStretch(1) 32 buttonLayout.addWidget(amendPushButton) 33 buttonLayout.addWidget(closePushButton) 34 mainLayout = QVBoxLayout(frame) 35 mainLayout.setMargin(10) 36 mainLayout.setSpacing(6) 37 mainLayout.addWidget(self.stack) 38 mainLayout.addLayout(buttonLayout) 39 self.connect(self.listWidget, SIGNAL("currentRowChanged(int)"), self.stack, SLOT("setCurrentIndex(int)")) 40 self.connect(closePushButton, SIGNAL("clicked()"), self, SLOT("close()")) 41 layout = QHBoxLayout(self) 42 layout.addWidget(mainSplitter) 43 self.setLayout(layout) 44 #例 20 代码开始----------------------- 45 self.faderWidget = None 46 self.connect(self.listWidget, SIGNAL("currentItemChanged(QListWidgetItem)"), self.changePage) 47 self.connect(self.stack, SIGNAL("currentChanged(int)"), self.fadeInWidget) 48 49 def changePage(self, current, previous): 50 if not current: 51 current = previous 52 self.stack.setCurrentWidget(current) 53 54 def fadeInWidget(self, index): 55 self.faderWidget = FaderWidget(self.stack.widget(index)) 56 self.faderWidget.start() 57 58 class FaderWidget(QWidget): 59 def __init__(self, parent=None): 60 super(FaderWidget, self).__init__(parent) 61 if parent: 62 self.startColor = parent.palette().window().color() 63 else: 64 self.startColor = Qt.White 65 self.currentAlpha = 0 66 self.duration = 1000 67 68 self.timer = QTimer(self) 69 self.connect(self.timer, SIGNAL("timeout()"), self.update) 70 self.setAttribute(Qt.WA_DeleteOnClose) 71 self.resize(parent.size()) 72 73 def start(self): 74 self.currentAlpha = 255 75 self.timer.start(100) 76 self.show() 77 78 def paintEvent(self, event): 79 semiTransparentColor = self.startColor 80 semiTransparentColor.setAlpha(self.currentAlpha) 81 painter = QPainter(self) 82 painter.fillRect(self.rect(), semiTransparentColor) 83 self.currentAlpha -= (255*self.timer.interval()/self.duration) 84 85 if self.currentAlpha <= 0: 86 self.timer.stop() 87 self.close() 88 #例 20 代码结束----------------------- 89 90 class BaseInfo(QWidget): 91 def __init__(self, parent=None): 92 super(BaseInfo, self).__init__(parent) 93 label1=QLabel(self.tr("用户名:")) 94 label2=QLabel(self.tr("姓名:")) 95 label3=QLabel(self.tr("性别:")) 96 label4=QLabel(self.tr("部门:")) 97 label5=QLabel(self.tr("年龄:")) 98 otherLabel=QLabel(self.tr("备注:")) 99 otherLabel.setFrameStyle(QFrame.Panel|QFrame.Sunken) 100 userLineEdit=QLineEdit() 101 nameLineEdit=QLineEdit() 102 sexComboBox=QComboBox() 103 sexComboBox.insertItem(0, self.tr("男")) 104 sexComboBox.insertItem(1, self.tr("女")) 105 departmentTextEdit=QTextEdit() 106 ageLineEdit=QLineEdit() 107 labelCol=0 108 contentCol=1 109 leftLayout=QGridLayout() 110 leftLayout.addWidget(label1, 0, labelCol) 111 leftLayout.addWidget(userLineEdit, 0, contentCol) 112 leftLayout.addWidget(label2, 1, labelCol) 113 leftLayout.addWidget(nameLineEdit, 1, contentCol) 114 leftLayout.addWidget(label3, 2, labelCol) 115 leftLayout.addWidget(sexComboBox, 2, contentCol) 116 leftLayout.addWidget(label4, 3, labelCol) 117 leftLayout.addWidget(departmentTextEdit, 3, contentCol) 118 leftLayout.addWidget(label5, 4, labelCol) 119 leftLayout.addWidget(ageLineEdit, 4, contentCol) 120 leftLayout.addWidget(otherLabel, 5, labelCol, 1, 2) 121 leftLayout.setColumnStretch(0, 1) 122 leftLayout.setColumnStretch(1, 3) 123 label6=QLabel(self.tr("头像:")) 124 iconLabel=QLabel() 125 icon=QPixmap("image/2.jpg") 126 iconLabel.setPixmap(icon) 127 iconLabel.resize(icon.width(), icon.height()) 128 iconPushButton=QPushButton(self.tr("改变")) 129 hLayout=QHBoxLayout() 130 hLayout.setSpacing(20) 131 hLayout.addWidget(label6) 132 hLayout.addWidget(iconLabel) 133 hLayout.addWidget(iconPushButton) 134 label7=QLabel(self.tr("个人说明:")) 135 descTextEdit=QTextEdit() 136 rightLayout=QVBoxLayout() 137 rightLayout.setMargin(10) 138 rightLayout.addLayout(hLayout) 139 rightLayout.addWidget(label7) 140 rightLayout.addWidget(descTextEdit) 141 mainLayout=QGridLayout(self) 142 mainLayout.setMargin(15) 143 mainLayout.setSpacing(10) 144 mainLayout.addLayout(leftLayout, 0, 0) 145 mainLayout.addLayout(rightLayout, 0, 1) 146 mainLayout.setSizeConstraint(QLayout.SetFixedSize) 147 148 class Contact(QWidget): 149 def __init__(self, parent=None): 150 super(Contact, self).__init__(parent) 151 label1=QLabel(self.tr("电子邮件:")) 152 label2=QLabel(self.tr("联系地址:")) 153 label3=QLabel(self.tr("邮政编码:")) 154 label4=QLabel(self.tr("移动电话:")) 155 label5=QLabel(self.tr("办公电话:")) 156 mailLineEdit=QLineEdit() 157 addressLineEdit=QLineEdit() 158 codeLineEdit=QLineEdit() 159 mpLineEdit=QLineEdit() 160 phoneLineEdit=QLineEdit() 161 receiveCheckBox=QCheckBox(self.tr("接收留言")) 162 layout=QGridLayout(self) 163 layout.addWidget(label1, 0, 0) 164 layout.addWidget(mailLineEdit, 0, 1) 165 layout.addWidget(label2, 1, 0) 166 layout.addWidget(addressLineEdit, 1, 1) 167 layout.addWidget(label3, 2, 0) 168 layout.addWidget(codeLineEdit, 2, 1) 169 layout.addWidget(label4, 3, 0) 170 layout.addWidget(mpLineEdit, 3, 1) 171 layout.addWidget(receiveCheckBox, 3, 2) 172 layout.addWidget(label5, 4, 0) 173 layout.addWidget(phoneLineEdit, 4, 1) 174 175 class Detail(QWidget): 176 def __init__(self, parent=None): 177 super(Detail, self).__init__(parent) 178 label1=QLabel(self.tr("国家/地区:")) 179 label2=QLabel(self.tr("省份:")) 180 label3=QLabel(self.tr("城市:")) 181 label4=QLabel(self.tr("个人说明:")) 182 countryComboBox=QComboBox() 183 countryComboBox.addItem(self.tr("中华人民共和国")) 184 countryComboBox.addItem(self.tr("香港")) 185 countryComboBox.addItem(self.tr("台北")) 186 countryComboBox.addItem(self.tr("澳门")) 187 provinceComboBox=QComboBox() 188 provinceComboBox.addItem(self.tr("安徽省")) 189 provinceComboBox.addItem(self.tr("北京市")) 190 provinceComboBox.addItem(self.tr("江苏省")) 191 cityLineEdit=QLineEdit() 192 remarkTextEdit=QTextEdit() 193 layout=QGridLayout(self) 194 layout.addWidget(label1, 0, 0) 195 layout.addWidget(countryComboBox, 0, 1) 196 layout.addWidget(label2, 1, 0) 197 layout.addWidget(provinceComboBox, 1, 1) 198 layout.addWidget(label3, 2, 0) 199 layout.addWidget(cityLineEdit, 2, 1) 200 layout.addWidget(label4, 3, 0) 201 layout.addWidget(remarkTextEdit, 3, 1) 202 203 app=QApplication(sys.argv) 204 main=StockDialog() 205 main.show() 206 app.exec_()
FaderWidget 继承自 QWidget,包含一个 start()函数,调用 start()函数即开始 FaderWidget 窗体的
渐变过程,重新实现了 paintEvent()函数,并声明了一个定时器变量定时调用 paintEvent()函数。
完成 FaderWidget 渐变窗体后,需在主对话框实现的合适位置和时机调用此渐变窗体以实现淡入淡出效果。
在 StackDialog 类中声明了两个槽函数,一个 changePage()完成页面切换的工作,一个
fadeInWidget()完成页面切换时的淡入淡出效果。
changePage()槽函数主要完成页面的切换工作。
fadeInWidget()槽函数在堆栈窗的页面发生变化时被调用,是实现页淡入淡出的关键函数,函数首先判断
是否已有渐变窗体对象存在,若已有则关闭已存在的渐变窗体,再以堆栈窗的当前窗体为父窗口创建渐变窗体
对象,并调用 start()函数开始窗体渐变,实现淡入淡出效果。

浙公网安备 33010602011771号