【前言】前几日通过编写命令行通讯录,掌握了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. arduino八段数码管使用

    一:八段数码管的使用 控制要求:0-9的计时数据 实物连接图: 控制代码: //智慧自动化2018.6.11 ;//定义数字接口7 连接a 段数码管 ;// 定义数字接口6 连接b 段数码管 ;// ...

  2. hdu1232畅通工程(并查集,简单题)

    传送门 最少好要修多少条路太能使全部城镇连通.只要用并查集算可以连通的城市的组数,修的路就是组数减1 #include<bits/stdc++.h> using namespace std ...

  3. Jmeter+ant+jenkins接口自动化测试 平台搭建(二)

    一.依赖文件配置 1.在ant目录C:\apache-ant-1.10.5下新建一个demo文件夹,并将jmeter测试脚本放在该文件夹中 2.将\apache-jmeter-3.3\extras下面 ...

  4. OpenGL学习笔记(6) 基础光照的计算方法

    这个笔记只是冯氏光照模型下漫反射光以及镜面光照的计算方式的笔记 基础光照 基础光照分为环境光,漫反射光,镜面光照 环境光 环境光是一个常量,表示在没有光源的情况下物体的光 漫反射光 漫反射光分量的计算 ...

  5. selenium的基本定位方式总结

    Selenium提供了8种定位方式. id name class name tag name link text partial link text xpath css selector 这8种定位方 ...

  6. sqli-labs学习笔记 DAY8

    DAY 8 sqli-lab Page-3 sqli-labs lesson 38 What is Stacked injection? https://blog.csdn.net/Fly_hps/a ...

  7. Tomcat分析

    最近闲来无事,总结了一下tomcat的一些知识,分享出来供大家参考,如有错误,请及时与我联系. 1. 入门示例:虚拟主机提供web服务 该示例通过设置虚拟主机来提供web服务,因为是入门示例,所以设置 ...

  8. python3.6环境中django2.0与xadmin0.6结合的后台管理

    1.xadmin简介 django的admin管理后台页面很简洁,对个人来说做后台管理非常简单:xadmin的比较admin优化界面,看着也舒服. xadmin界面效果如下: 2.xadmin安装 从 ...

  9. PHP处理表单数据的一个安全回顾(记录教训)

    曾经看过一个安全文章中写过这么一条 表单输入数据要做 htmlspecialchars_decode 表单输出数据要做htmlspecialchars 当时还不是很理解为什么,自己也没遇到问题,所以就 ...

  10. node child_process模块

    NodeJs是一个单进程的语言,不能像Java那样可以创建多线程来并发执行.当然在大部分情况下,NodeJs是不需要并发执行的,因为它是事件驱动性永不阻塞.但单进程也有个问题就是不能充分利用CPU的多 ...