【前言】前几日通过编写命令行通讯录,掌握了Python的基本语法结构,于是开始向更高水平冲击,利用Eric与Qt Designer 编写一个带界面的小程序。本次实操中也确实遇到了不少问题,通过学习也都解决了,达到了学习进步的目的。

【吐槽】写博客比编程序难多了,程序写了一下午,博客写了一整天,这么费力的写出来,希望可以帮助到一些刚开始学习Python的朋友。由于我不是科班出身,编程纯属业余爱好,所以也是一边学一边编的,有不足的地方还请批评指正。

1.目标

编写一个倒计时时钟程序,用饼图的形式显示一天、一周、一个月以及一年已经过了多少时间还剩多少时间,用于提醒人珍惜时间。

2.实现方法

  • 由于准库time模块不能继承,创建一个新的时间的类,使用标准库time模块来进行时间的相关操作。
  • 使用Eric与Qt Designer开发
  • 使用matplotlib的pie函数绘制饼图

3.菜鸟难点

  1. 对time模块不熟悉,不知如何使用。
  2. Qt Designer的使用。
  3. Qt中添加matplotlib组件窗口。

3.1 time模块

time 模块提供了一些处理日期和一天内时间的函数。它是建立在 C 运行时库的简单封装。

给定的日期和时间可以被表示为浮点型(从参考时间, 通常是 1970.1.1 到现在经过的秒数,即 Unix 格式),或者一个表示时间的 struct (类元组)。

方法

3.1.1 time()

返回从1970.1.1 到现在经过的秒数

>>> import time
>>> time.time()
1471794516.136771

3.1.2 localtime()

返回元组形式的时间,

>>> import time
>>> time.localtime()
time.struct_time(tm_year=2016, tm_mon=8, tm_mday=21, tm_hour=23, tm_min=49, tm_sec=57, tm_wday=6, tm_yday=234, tm_isdst=0)
名称 含义
tm_year
tm_mon
tm_mday
tm_hour
tm_min
tm_sec
tm_wday 周几(0-6)
tm_yday 一年中的第几天
tm_isdst -1代表系统判断是否为夏时令
0代表非夏时令
1代表夏时令

3.1.3 ctime()

返回字符串形式的时间

>>> import time
>>> time.ctime()
'Sun Aug 21 23:50:56 2016'

3.1.4 strptime()

将字符串形式的时间转换成元组形式的时间

符号 含义
%y 两位数年份(00-99 )
%Y 四位数年份(000-9999 )
%m 月份(01-12)
%d 日期 0-31
%H 24小时制小时数( 0-23 )
%I 12小时制小时数( 01-12 )
%M 分钟数(00-59)
%S 秒(00-59)
%a 本地星期简化名称
%A 本地星期完整名称
%b 本地月份简化名称
%B 本地月份完整名称
%c 本地相应的日期表示和时间表示
%j 年内的第几天(001-366)
%p 本地A.M.或 P.M.
%U 一年中的星期数(00-53),星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53),星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区名称
%% %号
>>> import time
>>> time.strptime('20160821','%Y%m%d')
time.struct_time(tm_year=2016, tm_mon=8, tm_mday=21, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=234, tm_isdst=-1)

3.1.5 strftime()

将元组形式的字符串按照指定格式转换成字符串形式

>>> import time
>>> time.strftime('%Y%m%d',(2016,8,21,0,0,0,6,234,0))
'20160821'

3.1.6 mktime()

讲元组形式的时间转换成从19700101累计的秒数

>>> import time
>>> time.mktime((2016,8,21,0,0,0,6,234,0))
1471708800.0

3.2 Eirc与Qt Designer的使用

本部分结合项目编写一起讲解。

3.3Qt中添加matplotlib组件窗口

在Qt中添加matplotlib组件窗口需要创建一个新的类mplwidget,在这个类中创建matplotlib的画布,然后在Qt designer中添加一个普通的Widget,然后将这个widget提升为我们所建的类mplwidget。

4.项目编写

4.1 创建项目

  1. 打开Eric,单击菜单栏【项目】-【新建】

  2. 输入“项目名称”,选择“项目文件夹”,点击【OK】

4.2创建窗体

  1. 在Eric“项目浏览器”的“窗体”中,单击右键,选择【新建窗体】

  2. 选择窗体类型“主窗口”,点击【OK】

  3. 输入窗体文件名,点击【Save】

  4. 在项目浏览器中,右键点击新建的.ui窗体文件,选择【在Qt设计师中打开】

  5. 打开Qt Designer后,会有几个基本的窗口,你自己的窗口“MainWindow”、“窗口部件盒”、“对象查看器”、“属性编辑器”,其他的窗口可从菜单栏“视图”窗口选择。

    拖拽“MainWindows”设置窗口的初始大小

    从“窗口部件盒”拖4个Widget到“MainWindow”

  6. 在“MainWindow”4个Widget以外的地方单击右键,选择【布局】-【水平布局】

  7. 在一个Widget上单击右键,选择【提升为】

  8. 在“提升的类名称”中输入要创建的自定义的widget类名称,点击【添加】

  9. 选中“提升的类”中新建的那个类,点击【提升】

  10. 选中Widget组件,在右侧的“属性编辑器”中将objectName改为mpl···Widget

  11. 保存文件,退出Qt Designer。
  12. 右击Eric“项目浏览器”中的.ui窗体文件,选择【编译窗体】,生成文件Ui_countdownmainwindow.py

  13. 打开生成的文件,将from mplpiewidget import MplPieWidget 剪切至class Ui_MainWindow(object):上面,保存文件。

4.4 自定义Widget类的编写

  • 单击Eric工具栏新建按钮,创建一个空白文档,保存为名为‘mplpiewidget.py’的文件。

  • 伪代码
# 导入PyQt5的图形界面组件模块QtGui,非图形类模块QtCore,基础界面控件模块QtWidgets,
# 导入matplotlib库中qt5后端,用于实现在qt5的组件里绘制matplotlib图像。
# 导入matplotlib的figure模块,figure模块包含所有画图的元素。
# 创建matplotlib的画布类MplCanvas,继承于qt5agg的figurecanvas
#初始化
#创建figure,Axis
#超类初始化
#将widget设置成expandable,随窗口变化
#系统更新widget设置
#创建自定义widget类MplPieWidget,继承于QtWidget.QWidget
#初始化
#超类初始化
#创建MplCanvas实例画布
#创建垂直布局的容器
#在容器中添加画布
#设置垂直布局生效
  • 编写代码
# 导入PyQt5的图形界面组件模块QtGui,非图形类模块QtCore,基础界面控件模块QtWidgets,
from PyQt5 import QtGui, QtCore, QtWidgets
# 导入matplotlib库中qt5后端,用于实现在qt5的组件里绘制matplotlib图像。
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
# 导入matplotlib的figure模块,figure模块包含所有画图的元素。
from matplotlib.figure import Figure # 创建matplotlib的画布类MplCanvas,继承于qt5agg的figurecanvas
class MplCanvas(FigureCanvas): #初始化
def __init__(self):
#创建figure,Axis
self.fig= Figure()
self.ax= self.fig.add_subplot(111)
#超类初始化
FigureCanvas.__init__(self,self.fig)
#将widget设置成expandable,随窗口变化
FigureCanvas.setSizePolicy(self,\
QtWidgets.QSizePolicy.Expanding,\
QtWidgets.QSizePolicy.Expanding)
#系统更新widget设置
FigureCanvas.updateGeometry(self) #创建自定义widget类MplPieWidget,继承于QtWidget.QWidget
class MplPieWidget(QtWidgets.QWidget): #初始化
def __init__(self, parent= None):
#超类初始化
QtWidgets.QWidget.__init__(self,parent)
#创建MplCanvas实例画布
self.canvas= MplCanvas()
#创建垂直布局的容器
self.vbl= QtWidgets.QVBoxLayout()
#在容器中添加画布
self.vbl.addWidget(self.canvas)
#设置垂直布局生效
self.setLayout(self.vbl)

4.4 Time类编写

  • 单击Eric工具栏新建按钮,创建一个空白文档,保存为名为‘mytime.py’的文件。
  • 伪代码
#导入time模块
#创建Time类
#获取现在的年、月、日、时、分、秒、星期以及今天是今年的第几天
#将值赋给year,month,day,hour,minute,second,weekday,yearday #创建一个方法,根据是不是闰年返回今年的总天数
#if year能够被400整除:
#天数为366
#elif year能被100整除:
#天数为365
#elif year能被4整除:
#天数为366
#else:
#天数为365
#返回天数
#创建本年天数变量daysOfYear #创建一个方法,返回本月天数
#if month是1,3,5,7,8,10,12月:
#天数为31
#elif month是4,6,9,11月:
#天数是30
#elif 今年是闰年:
#天数为29
#else:
#天数为28
#返回天数 #创建本月天数变量daysOfMonth #创建一个方法,将字符串形式时间转换成时间戳
#将year,month,day转换成字符串连在一起
#将时间戳形式时间返回 #将今天的时间(时分秒)换算成秒数
  • 编写代码
#导入time模块
import time #创建Time类
class Time(object): #获取现在的年、月、日、时、分、秒、星期以及今天是今年的第几天
#将值赋给year,month,day,hour,minute,second,weekday,yearday
localTime= time.localtime()
year,month,day,hour,minute,second,weekday,yearday= localTime[0:-1] #创建一个方法,根据是不是闰年返回今年的总天数
def totalDaysOfYear(year):
#if year能够被400整除:
if year% 400== 0:
#天数为366
totalDays= 366
#elif year能被100整除:
elif year% 100== 0:
#天数为365
totalDays= 365
#elif year能被4整除:
elif year% 4== 0:
#天数为366
totalDays= 366
#else:
else:
#天数为365
totalDays= 365
#返回天数
return totalDays #创建本年天数变量daysOfYear
daysOfYear= totalDaysOfYear(year) #创建一个方法,返回本月天数
def totalDaysOfMonth(month):
#if month是1,3,5,7,8,10,12月:
if month in [1,3,5,7,8,10,12]:
#天数为31
totalDays= 31
#elif month是4,6,9,11月:
elif month in [4,6,9,11]:
#天数是30
totalDays= 30
#elif 今年是闰年:
elif self.daysOfYear== 366:
#天数为29
totalDays= 29
#else:
else:
#天数为28
totalDays= 28
#返回天数
return totalDays #创建本月天数变量daysOfMonth
daysOfMonth= totalDaysOfMonth(month) #创建一个方法,将字符串形式时间转换成时间戳
def transformTime(year,month,day):
#将year,month,day转换成字符串连在一起
nowtime= str(year)+ '-'+ str(month)+ '-'+ str(day)
#将时间戳形式时间返回
return time.mktime(time.strptime(nowtime,'%Y-%m-%d')) #将今天的时间(时分秒)换算成秒数
secondsOfTheDay= time.time()- transformTime(year,month,day)

4.5 主程序编写

1.Eric“项目浏览器”右击.ui文件选择【生成对话框代码】



2.选择【新建】类名



3.单击【OK】,项目中生成名为countdownmainwindow.py的文件



4.编辑countdownmainwindow.py

  • from .Ui_countdownmainwindow import Ui_MainWindow改为from Ui_countdownmainwindow import Ui_MainWindow
  • 导入我们写的Time类

from mytime import Time

  • 创建一个绘制饼图的方法
    def plotPie(self,widget,list,colors):
widget.canvas.ax.clear()
widget.canvas.ax.pie(list,explode= None, labels= None, colors= colors, \
labeldistance= 1.1, autopct= None,shadow= False, \
startangle= 90, pctdistance= 0.6)
widget.canvas.draw()
  • 创建列表,用于绘制饼图及设置饼图颜色
    #创建年列表=[今年剩余天数,已过天数]
yearList= [Time.daysOfYear- Time.yearday, Time.yearday]
yearColorsList= ['blue','gray']
#创建月列表=[本月剩余天数,已过天数]
monthList= [Time.daysOfMonth- Time.day, Time.day]
monthColorsList= ['blue','gray']
#创建周列表=[本周剩余天数,已过天数]
weekList= [6-Time.weekday, Time.weekday+1]
weekColorsList= ['blue','gray']
#创建日列表-[本天剩余秒数,已过秒数]
dayList= [24*60*60- Time.secondsOfTheDay, Time.secondsOfTheDay]
dayColorsList= ['blue','gray']
  • 在__init__方法中添加绘制饼图的方法
    def __init__(self, parent=None):
"""
Constructor @param parent reference to the parent widget
@type QWidget
"""
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.plotPie(self.mplYearWidget,ListOfPie.yearList,['blue','gray'])
self.plotPie(self.mplMonthWidget,ListOfPie.monthList,['blue','gray'])
self.plotPie(self.mplWeekWidget,ListOfPie.weekList,['blue','gray'])
self.plotPie(self.mplDayWidget,ListOfPie.dayList,['blue','gray'])
  • 在最后添加如下代码,将主窗口显示出来。
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
  • 完整代码为:
# -*- coding: utf-8 -*-

"""
Module implementing MainWindow.
""" from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QMainWindow
from countdown import ListOfPie
from Ui_CountdownMainWindow import Ui_MainWindow class MainWindow(QMainWindow, Ui_MainWindow):
"""
Class documentation goes here.
"""
def __init__(self, parent=None):
"""
Constructor @param parent reference to the parent widget
@type QWidget
"""
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.plotPie(self.mplYearWidget,ListOfPie.yearList,['blue','gray'])
self.plotPie(self.mplMonthWidget,ListOfPie.monthList,['blue','gray'])
self.plotPie(self.mplWeekWidget,ListOfPie.weekList,['blue','gray'])
self.plotPie(self.mplDayWidget,ListOfPie.dayList,['blue','gray']) def plotPie(self,widget,list,colors):
widget.canvas.ax.clear()
widget.canvas.ax.pie(list,explode= None, labels= None, colors= colors, \
labeldistance= 1.1, autopct= None,shadow= False, \
startangle= 90, pctdistance= 0.6)
widget.canvas.draw() if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec_())

4.6 程序的调试与运行

  • F5键为调试程序

    选中主程序调试,调试整个项目,如果没有错误直接运行

  • F2键为直接运行程序

5 程序演示


本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

想观看Matplotlib教学视频,了解更多Matplotlib实用技巧可关注

微信公众账号: MatplotlibClass

今日头条号:Matplotlib小讲堂

利用Eric+Qt Designer编写倒计时时钟的更多相关文章

  1. pyqt5对用qt designer设计的窗体实现弹出子窗口的示例

    pyqt5对用qt designer设计的窗体实现弹出子窗口的示例 脚本专栏 python 1. 用qt designer编写主窗体,窗体类型是MainWindow,空白窗口上一个按钮.并转换成mai ...

  2. 编写Qt Designer自定义控件(二)——编写自定义控件界面

    接上文:编写Qt Designer自定义控件(一)——如何创建并使用Qt自定义控件 既然是控件,就应该有界面,默认生成的控件类只是一个继承了QWidget的类,如下: #ifndef LOGLATED ...

  3. 编写Qt Designer自定义控件(一)——如何创建并使用Qt自定义控件

    在使用Qt Designer设计窗体界面时,我们可以使用Widget Box里的窗体控件非常方便的绘制界面,比如拖进去一个按钮,一个文本编辑器等.虽然Qt Designer里的控件可以满足我们大部分的 ...

  4. 编写Qt Designer自定义控件

    一)流程概述 在使用Qt Designer设计窗体界面时,我们可以使用Widget Box里的窗体控件非常方便的绘制界面,比如拖进去一个按钮,一个文本编辑器等.虽然Qt Designer里的控件可以满 ...

  5. qt利用QT designer构建第一个界面helloworld工程

    qt利用QT designer构建第一个界面helloworld工程原创ZJE_ANDY 发布于2017-04-07 20:25:28 阅读数 6613 收藏展开第一步:点击New Project 第 ...

  6. Qt Designer怎样加入资源文件

    Qt Designer中如果在设计UI界面的时候要加入一些图素,图标等资源的时候是不能直接添加进去的,需要在Qt开发目录下编写QRC文件 qrc文件格式如下: <RCC> <qres ...

  7. pyqt5 在qt designer后以弹窗的方式连接多个UI图形界面

    当我们通过pyqt开发时,eric6为我们提供了一个方便的工具:图形化的绘制UI工具--qt designer. 我们可以通过它开发多个UI,然后利用信号-槽工具,将功能代码附着在上面.也可以将多个界 ...

  8. 痞子衡嵌入式:超级好用的可视化PyQt GUI构建工具(Qt Designer)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是PyQt GUI构建工具Qt Designer. 痞子衡开博客至今已有好几年,一直以嵌入式开发相关主题的文章为主线,偶尔穿插一些其他技术 ...

  9. Qt Designer 的使用

    1. Qt Designer 快速入门 Qt Designer 是交互式可视化GUI设计工具,可以帮助我们快速开发 PyQt 程序的速度. 它生成的 UI 界面是一个后缀为 .ui 的文件,可以通过 ...

随机推荐

  1. javaweb学习5——JSP

    声明:本文只是自学过程中,记录自己不会的知识点的摘要,如果想详细学习JavaWeb,请到孤傲苍狼博客学习,JavaWeb学习点此跳转 本文链接:https://www.cnblogs.com/xdp- ...

  2. 如何推行Code Review

    这篇文章探讨的是如何在一个没有Code Review习惯的团队里面Code Review. 在进行Code Review的时候,审核人很多时候会对被审核人的代码指手画脚,在评价对方的代码,甚至是在批评 ...

  3. java抽象类与接口区别

    java抽象类与接口区别: abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力. abstr ...

  4. 琴声不等式--jensen

    (来自百度百科) 1. 凹函数,不加权 2. 凹函数,加权 3. 凸函数,不加权 4. 凸函数,加权 应用 在EM算法Q函数的推导中,用到了第二个不等式(凹函数,加权)

  5. Django中的Project和App的区别

    Django是一个非常流行的用python编写的Web框架,在使用Django之前,我们需要了解一些基本的概念,这样可以在使用Django的时候对其有一个更加深入的把握.本文主要介绍Django中两个 ...

  6. Ruby知识点三:运算符

    1.逻辑运算符 (1)条件1 || 条件2 条件1为假时,才需判断条件2 (2)条件1 && 条件2 条件1为真时,才需判断条件2 2.范围运算符 (1)x..y  从x到y,包括y ...

  7. iOS - Bundle 资源文件包生成和常见资源文件使用

    1.Bundle 文件 Bundle 文件,就是资源文件包.我们将许多图片.XIB.文本文件组织在一起,打包成一个 Bundle 文件.方便在其他项目中引用包内的资源. Bundle 文件是静态的,也 ...

  8. servlet 和 threadlocal 与 web容器(理解threadlocal)

    同步机制采用了“以时间换空间”的方式,提供一份变量,让不同的线程排队访问.而ThreadLocal采用了“以空间换时间”的方式,为每一个线程都提供了一份变量的副本,从而实现同时访问而互不影响. htt ...

  9. React的setState分析

    前端框架层出不穷,不过万变不离其宗,就是从MVC过渡到MVVM.从数据映射到DOM,angular中用的是watcher对象,vue是观察者模式,react就是state了. React通过管理状态实 ...

  10. “Hello World!”团队第六周第六次会议

    “Hello World!”团队第六周第六次会议   博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 八.checkout& ...