【转】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()函数开始窗体渐变,实现淡入淡出效果。

posted @ 2014-11-19 10:51  jakey.chen  阅读(681)  评论(0)    收藏  举报