你好,游客 登录 注册 搜索
背景:
阅读新闻

PyQt4 精彩实例分析

实例20 窗体的淡入淡出效果

[日期:2012-06-24] 来源:Linux社区  作者:chumpklutz [字体: ]

本实例实现一个窗体淡入淡出效果的例子,当窗体进行页面切换时,原页面的消失和新页面的显现并不是瞬间切换的,而是逐渐消隐和逐渐显现的过程。

本实例实现淡入淡出效果的基本原理可由下图描述。

 

当对话框由页面1切换至页面2时,在响应页面切换命令的同时,新建一个FaderWidget窗体,此窗体是一个与对话框等尺寸的空白窗体,此窗体由不透明逐渐变为完全透明,即实现页面的淡入淡出效果。

本实例将实例17的实现改造成淡入淡出效果,主对话框由一个列表框QListWidget和一个堆栈窗体QStackedWidget组成,列表框中列出了可显示的3个页面名称:“基本资料”,“联系方式”和“详细资料”,如下图所示。堆栈窗体中包含了对应的3个页面。

具体实现代码如下:

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

FaderWidget继承自QWidget,包含一个start()函数,调用start()函数即开始FaderWidget窗体的渐变过程,重新实现了paintEvent()函数,并声明了一个定时器变量定时调用paintEvent()函数。

第71-74行首先判断是否有父窗体存在,若有父窗体,则设置起始窗体颜色为父窗体的背景色,若没有父窗体,则设置起始窗体颜色为白色。

第76行设置透明度的初始值。

第77行设置渐变时长为1000毫秒。

第79行创建一个定时对象。

第80行连接定时器响应timeout()信号,每一间隔时间结束后调用一次update()函数重画窗体。

第81行设置FaderWidget的窗体属性为Qt.WA_DeleteOnClose,当整个对话框关闭时,此渐变窗体也同时关闭。

第82行设置FaderWidget窗体的的尺寸为父窗体的大小。

FaderWidget的start()函数显示此窗体并开始渐变。首先设置窗体显示的最初透明度为255,即不透明,启动定时器,以100毫秒为周期进行重画,最后调用show()函数显示此窗体。

第90行用一个QColor对象保存重绘窗体的颜色,设置为startColor,即父窗体的颜色或白色。

第91行设置此颜色的透明度。

第92行以FaderWidget窗体创建一个QPainter对象。

第93行利用此颜色填充整个窗体。

第94行修改currentAlpha值,第重绘一次透明度降低一定的值,直到透明度为0,即完全透明。

第96-98行对透明度的值进行判断,若透明度已小于或等于零,则停止定时器,也即不再调用重画命令,并关闭此FaderWidget窗体。

完成FaderWidget渐变窗体后,需在主对话框实现的合适位置和时机调用此渐变窗体以实现淡入淡出效果。

在StackDialog类中声明了两个槽函数,一个changePage()完成页面切换的工作,一个fadeInWidget()完成页面切换时的淡入淡出效果。

第54行的connect函数,为列表框currentItemChanged()信号连接响应槽函数changePage(),即当用户选择下拉列表框中的条目时,调用changePage()更改右侧堆栈窗中的显示页面。

第56行的connect函数,为堆栈窗的currentChanged()信号连接响应槽函数fadeInWidget(),即当堆栈窗的页面发生改变时调用fadeInWidget()来实现页面的淡入淡出效果。

changePage()槽函数主要完成页面的切换工作。

fadeInWidget()槽函数在堆栈窗的页面发生变化时被调用,是实现页淡入淡出的关键函数,函数首先判断是否已有渐变窗体对象存在,若已有则关闭已存在的渐变窗体,再以堆栈窗的当前窗体为父窗口创建渐变窗体对象,并调用start()函数开始窗体渐变,实现淡入淡出效果。

linux
【内容导航】
第1页:实例1 Hello Kitty! 第2页:实例2 标准对话框的使用
第3页:实例3 各类位置信息 第4页:实例4 使用标准输入框
第5页:实例5 各种消息框的使用 第6页:实例6 实现QQ抽屉效果
第7页:实例7 表格的使用 第8页:实例8 使用进度条
第9页:实例9 利用Qt Designer设计一个对话框 第10页:实例10 在程序中使用Ui
第11页:实例11 动态加载Ui 第12页:实例12 基本布局管理
第13页:实例13 多文档 第14页:实例14 分割窗口
第15页:实例15 停靠窗口 第16页:实例16 堆栈窗口
第17页:实例17 综合布局实例 第18页:实例18 可扩展对话框
第19页:实例19 利用QPalette改变控件颜色 第20页:实例20 窗体的淡入淡出效果
第21页:实例21 不规则窗体 第22页:实例22 电子钟
第23页:实例23 程序启动画面 第24页:实例24 基本QMainWindow主窗口程序
第25页:实例25 打印文本 第26页:实例26 打印图像
相关资讯       PyQt4 
本文评论   查看全部评论 (1)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款
第 1 楼
* 匿名 发表于 2013/4/8 12:47:12
11