2.利用Python制作电子版电影台历

2020嗖的一下就要过去了,想买一个豆瓣电影台历,官方价格是98,想着有点贵,就想利用学习的Python制作一个电子版的台历,效果图如下


非周六周日
带Tips
周六周日

界面整体的布局:头部仿台历便签空,内容(电影名称,类型,发行时间,豆瓣分数),底部左(星期,日期,农历日期),底部右(便签输入框)

开发的整体思路是:
1.利用Python获取豆瓣网站排行榜的Top50的所有电影海报及信息
2.利用PyQt5实现界面编程

一 获取电影海报

1.获取排行榜所有的电影类型并创建本地文件夹

豆瓣电影排行类型
import json
import requests
import os
from bs4 import BeautifulSoup
import urllib.request as urlRequest

movieTypes=[]
ghead={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0'}
def getType():
    global htmlFiles
    head={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0'}
    url = 'https://movie.douban.com/chart'
    response = requests.get(url,headers=head)
    print(response.status_code)
    if response.status_code==200:
        soup = BeautifulSoup(response.text,"html.parser")
        content = soup.find_all(name='div',attrs={"class":"types"})
        # print(content[0])
        #soup = BeautifulSoup(content[0],"html.parser")
        content = content[0].find_all(name='span')
        # print(content)
        for i in range(len(content)):
            mhref='https://movie.douban.com'+content[i].find_all(name='a')[0].get('href')
            movieTypes.append(mhref)
            # print(mhref)
        for j in range(len(movieTypes)):
            print(movieTypes[j])
        print('获取列表成功'+str(len(movieTypes)))
    else:
        print("获取主页的电影排行榜列表错误")

本地生成文件结构图

2.获取每种类型的Top50并将结果保存到本地

每种类型排行调用接口
返回结果
def getEveryTypeTop50():
    rootDir='D:\豆瓣电影'
    for i in range(len(movieTypes)):
        xurl = movieTypes[i];
        params=str(xurl).split('?')[1].split('&')
        print(params[0])
        print(params[1])
        #创建文件夹
        dirPath=rootDir+'\\'+str(params[0]).split('=')[1]
        try:
            if not os.path.exists(rootDir+'\\'+str(params[0]).split('=')[1]):
                os.mkdir(rootDir+'\\'+str(params[0]).split('=')[1])
        except OSError:
            print('创建电影文件夹错误')
            pass

        #开始调用TOP50接口
        urltop50='https://movie.douban.com/j/chart/top_list?'+str(params[1])+'&interval_id=100%3A90&start=0&limit=50'
        print(urltop50)
        head={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0'}
        #top50返回结果的文件
        filePath=dirPath+'\\'+'top50.txt'

        top50Response = requests.get(urltop50,headers=head)
        if top50Response.status_code==200:
            print(top50Response.text)
            with open(filePath,'a',encoding='utf-8') as file:
                file.write(str(top50Response.text))
        else:
            print(str(params[0]).split('=')[1]+'获取top50失败')
返回的Top50结果

以上的接口调用注意&start=0&limit=50原网页中是20一页的调用。


解析Json

3.获取电影海报并保存本地

获取封面接口
def readfile():
    rootPath='D:\豆瓣电影'
    dirs = os.listdir(rootPath)
    for x in range(0,len(dirs)):
        print(str(x)+'_'+dirs[x])
    # exit(0)
    # for m in range(len(dirs)):
    for m in range(25,len(dirs)):
        print(dirs[m])
        with open(rootPath+'\\'+str(dirs[m])+'\\'+'top50.txt','r',encoding='utf-8') as file:
            content = file.read()
            top50List=json.loads(str(content))
            for n in range(0,len(top50List)):
            # for n in range(1):
                item = top50List[n]
                id = item['id']
                title = item['title']
                release_date=item['release_date']
                score=item['score']
                cover_url=item['cover_url']
                print(str(m))
                print(dirs[m])
                print(id)
                print(title)
                print(release_date)
                print(score)
                print(cover_url)
                print(n)
                cover_url=str(cover_url).replace('s_ratio_poster','l')
                cover_url = str(cover_url).replace('jpg', 'webp')
                print(cover_url)
                # 下载图片
                opener = urlRequest.build_opener()
                opener.addheaders= [('upgrade-insecure-requests','1'),('User-Agent',
                                      'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0')]
                urlRequest.install_opener(opener)
                savefilepath = rootPath + '\\' + str(dirs[m]) + '\\'
                savefilename = title + '_' + release_date + '_' + id + '_' + score + '_' + '.jpg'
                urlRequest.urlretrieve(cover_url, '{}{}.jpg'.format(savefilepath, savefilename))

获取图片结果

二 PyQt5设置日历界面

1.下载开源的农历日历看看别人怎么做的

https://github.com/fztransit/Luni-Solar-Calendar

2.在此基础上进行简化修改

from CustomizeWidgets import *
from PerpetualCalendar import *
from threading import Timer
import sched
import os
import random

# global clicked
clicked=0
global jpgFiles
jpgFiles = []
global rootJpgDir
rootJpgDir = 'D:\豆瓣电影'
global isFirst
isFirst = True
mytimes=0

class GUI(QMainWindow):
    def __init__(self):
        super().__init__()
        self.wnlWidget = QWidget()
        self.mainWidget = QWidget()
        desktop = QApplication.desktop()
        print("屏幕宽:" + str(desktop.width()))
        print("屏幕高:" + str(desktop.height()))

        global screenH
        screenH = desktop.height()
        global screenW
        screenW = desktop.width()

        # global clickedTimes
        clickedTimes=0
        # if isFirst:
        global mytimes
        mytimes = random.randint(0,1291)
        print('mytimes='+str(mytimes))
        self.getAllJpg(rootJpgDir)
            # isFirst=False
        for i in range(len(jpgFiles)):
            print(str(i)+str(jpgFiles[i]))
        self.setupUI()
        self.timerTask()
    def setupUI(self):
        pe = QPalette()
        pe.setColor(QPalette.Window, QColor(250, 255, 255))  # F0FFFF、FFFAFA、FFFAF0
        self.setPalette(pe)
        self.setFixedSize(500, 1000)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.bmp = QBitmap(500,1000)
        self.bmp.fill()
        self.Painter = QPainter(self.bmp)
        self.Painter.setPen(Qt.NoPen)
        self.Painter.setBrush(Qt.black)
        self.Painter.drawRoundedRect(self.bmp.rect(), 10, 10)
        self.setMask(self.bmp)
        # self.move(screenW-510,20)
        self.move(1920 - 510, 10)
        # self.setAttribute(Qt.WA_TranslucentBackground)
        # self.setWindowTitle("万年历")

        self.setCentralWidget(self.mainWidget)
        #设置距离上端的宽高
        self.setContentsMargins(0,50,0,0)
        # self.mainWidget.setLayout()
        # self.calendarUI()
        # displayDate(self)
        self.movieCalendarUi()
        self.show()
    def paintEvent(self, *args, **kwargs):
        qp = QPainter()
        qp.begin(self)
        self.drawRectangles(qp)
        qp.end()
    def drawRectangles(self,qp):
        col = QColor(0x33, 0xbe, 0xe5)
        col.setNamedColor('#33b5e5')
        qp.setPen(col)
        brushColor = QColor(0x05,0x5f,0xcd)
        qp.setBrush(brushColor)
        # 宽度是500
        for m in range(1,11):
            qp.drawRect(15+(m-1)*50,15,20,20)

        #画线
        pen = QPen(Qt.darkGray,3,Qt.SolidLine)
        pen.setColor(brushColor)
        qp.setPen(pen)
        qp.drawLine(0,50,500,50)
        qp.drawLine(0, 55, 500, 55)


        #
        # qp.setBrush(QColor(200, 0, 0))
        # qp.drawRect(10, 15, 90, 60)
        # qp.drawRect(130, 15, 90, 60)
        # qp.setBrush(QColor(25, 0, 90, 200))
        # qp.drawRect(250, 15, 90, 60)
        # qp.setBrush(QColor(255, 80, 0, 160))

    def movieCalendarUi(self):

        #mainWidget主容器
        #qvboxLayout主垂直布局
        self.qvboxLayout = QVBoxLayout()
        self.headLayout = QHBoxLayout()
        self.headLayout.setSpacing(10)
        #电影名字和上映时间
        self.movieName = QLabel()
        # self.movieName.setText("{}".format(font('爱尔兰人', 24, "black")))
        self.movieType = QLabel()
        # self.movieType.setText("{}".format(font('[犯罪]', 18, "blue")))
        self.movieTime = QLabel()
        # self.movieTime.setText("{}".format(font('2019-09-27 8.8', 18, "blue")))
        global mytimes

        print(str(mytimes % len(jpgFiles)))
        path = jpgFiles[mytimes % len(jpgFiles)]
        print(path)
        paths = str(path).split('\\')
        print(str(paths))
        type = paths[2]
        name = paths[3]
        names = str(name).split('_')
        self.movieName.setText("{}".format(font(names[0], 24, "black")))
        self.movieType.setText("{}".format(font('[' + type + ']', 18, "blue")))
        self.movieTime.setText("{}".format(font(names[1] + ' ' + names[3], 18, "blue")))

        self.headLayout.addWidget(self.movieName)
        self.headLayout.addWidget(self.movieType)
        self.headLayout.addWidget(self.movieTime)
        self.headLayout.addStretch(1)

        self.qvboxLayout.addLayout(self.headLayout)
        self.moviePic = QPixmap(path)
        # self.moviePic = QPixmap('D:\豆瓣电影\犯罪\爱尔兰人_2019-09-27_6981153_8.8_.jpg.jpg')
        # moviePic.addFile()
        # moviePic.scaledToWidth(90)
        # self.qSize=QSize(300,500)
        self.moviePic=self.moviePic.scaled(500,700)
        self.movieImg = QLabel()
        # movieImg.mouseDoubleClickEvent(self.doubl)
        # movieImg.width=(10)
        # movieImg.height=(10)
        self.movieImg.setPixmap(self.moviePic)
        self.qvboxLayout.addWidget(self.movieImg)
        self.footLayout = QHBoxLayout()
        self.footLeftLayout = QVBoxLayout()
        self.footLeftLayout.setAlignment(Qt.AlignCenter)
        self.footRightLayout=QVBoxLayout()
        yearText,monthText,dayText,wdayText,lunarMonth,lunarDay=getDateInfo()
        self.monthLabel = QLabel()
        self.dayLabel = QLabel()
        self.lunarLabel = QLabel()
        print("wdayText="+wdayText)
        weeks = [u"星期日",u"星期一", u"星期二", u"星期三", u"星期四", u"星期五", u"星期六"]
        if wdayText=='6' or wdayText=='7':
            self.monthLabel.setText("{}".format(font(str(weeks[int(wdayText)]), 30, "red")))
            self.dayLabel.setText("{}".format(font(dayText, 90, "red")))
            self.lunarLabel.setText("{}".format(font(lunarMonth+'月'+lunarDay, 20, "red")))
        else:
            self.monthLabel.setText("{}".format(font(str(weeks[int(wdayText)]), 30, "green")))
            self.dayLabel.setText("{}".format(font(dayText, 90, "green")))
            self.lunarLabel.setText("{}".format(font(lunarMonth+'月'+lunarDay, 20, "green")))

        self.footLeftLayout.addWidget(self.monthLabel)
        self.footLeftLayout.addWidget(self.dayLabel)
        self.footLeftLayout.addWidget(self.lunarLabel)
        self.tips1Label = QLineEdit()
        self.tips2Label = QLineEdit()
        self.tips3Label = QLineEdit()
        self.tips1Label.setStyleSheet("QLineEdit{background:#ff8800;height:48;font-size:30px;color:white}")
        self.tips2Label.setStyleSheet("QLineEdit{background:#9933cc;height:48;font-size:30px;color:white}")
        self.tips3Label.setStyleSheet("QLineEdit{background:#008577;height:48;font-size:30px;color:white}")
        self.footRightLayout.addWidget(self.tips1Label,1)
        self.footRightLayout.addWidget(self.tips2Label, 1)
        self.footRightLayout.addWidget(self.tips3Label, 1)
        self.footLayout.addLayout(self.footLeftLayout,1)
        self.footLayout.addLayout(self.footRightLayout,3)
        self.qvboxLayout.addLayout(self.footLayout)
        # self.qvboxLayout.addStretch(1)
        self.mainWidget.setLayout(self.qvboxLayout)



    def mousePressEvent(self, evt):
        x = evt.x()
        y=evt.y()

        subWidget = self.childAt(x,y)
        if subWidget==self.movieImg:
            # print("0000000000")
            global mytimes
            # if mytimes>0:
            #   print(str(mytimes))
            # else:


            print(str(mytimes%len(jpgFiles)))
            path = jpgFiles[mytimes%len(jpgFiles)]
            print(path)
            paths=str(path).split('\\')
            print(str(paths))
            type = paths[2]
            name = paths[3]
            names = str(name).split('_')
            self.movieName.setText("{}".format(font(names[0], 24, "black")))
            self.movieType.setText("{}".format(font('['+type+']', 18, "blue")))
            self.movieTime.setText("{}".format(font(names[1]+' '+names[3], 18, "blue")))
            self.moviePic = QPixmap(path)
            # self.moviePic = QPixmap('D:\豆瓣电影\犯罪\蝙蝠侠:黑暗骑士_2008-07-14_1851857_9.2_.jpg.jpg')
            # moviePic.addFile()
            # moviePic.scaledToWidth(90)
            # self.qSize=QSize(300,500)
            self.moviePic = self.moviePic.scaled(500, 700)
            self.movieImg.setPixmap(self.moviePic)
            # global clicked
            # x = clicked+1;
            # clicked=+1
            # clicked=clicked.__add__(1)
            mytimes = mytimes + 1;
            print(str(mytimes))
            # self.clickedTimes=self.clickedTimes+1
            print(str(x) + ',' + str(y))
        print(str(subWidget))


    def timerTask(self):
        # time=null
        # while True:
        #   time.sleep(1)
        #   self.task()
        self.timex=None

        if self.timex==None:
            print('null')
            self.timex = Timer(60, self.task, ())
            self.timex.start()
        else:
            print('zzzz')
            # self.timex.cancel()
            self.timex.start()

        # scheduler = sched.scheduler(time.time,time.sleep)
        # scheduler.enter(10,1,self.task())
        # scheduler.run()

    def task(self):

        global mytimes
        print(str(mytimes % len(jpgFiles)))
        path = jpgFiles[mytimes % len(jpgFiles)]
        print(path)
        paths = str(path).split('\\')
        print(str(paths))
        type = paths[2]
        name = paths[3]
        names = str(name).split('_')
        self.movieName.setText("{}".format(font(names[0], 24, "black")))
        self.movieType.setText("{}".format(font('[' + type + ']', 18, "blue")))
        self.movieTime.setText("{}".format(font(names[1] + ' ' + names[3], 18, "blue")))
        self.moviePic = QPixmap(path)
        # self.moviePic = QPixmap('D:\豆瓣电影\犯罪\蝙蝠侠:黑暗骑士_2008-07-14_1851857_9.2_.jpg.jpg')
        # moviePic.addFile()
        # moviePic.scaledToWidth(90)
        # self.qSize=QSize(300,500)
        self.moviePic = self.moviePic.scaled(500, 700)
        self.movieImg.setPixmap(self.moviePic)
        # global clicked
        # x = clicked+1;
        # clicked=+1
        # clicked=clicked.__add__(1)
        mytimes = mytimes + 1;
        yearText, monthText, dayText, wdayText, lunarMonth, lunarDay = getDateInfo()
        print("wdayText="+wdayText)
        weeks = [u"星期日",u"星期一", u"星期二", u"星期三", u"星期四", u"星期五", u"星期六"]
        if wdayText=='6' or wdayText=='7':
            self.monthLabel.setText("{}".format(font(str(weeks[int(wdayText)]), 30, "red")))
            self.dayLabel.setText("{}".format(font(dayText, 90, "red")))
            self.lunarLabel.setText("{}".format(font(lunarMonth+'月'+lunarDay, 20, "red")))
        else:
            self.monthLabel.setText("{}".format(font(str(weeks[int(wdayText)]), 30, "green")))
            self.dayLabel.setText("{}".format(font(dayText, 90, "green")))
            self.lunarLabel.setText("{}".format(font(lunarMonth+'月'+lunarDay, 20, "green")))

        self.timerTask()



    def closeEvent(self, *args, **kwargs):
        super().closeEvent(*args, **kwargs)
        print("cccccccccccc")
        self.timex.cancel()
        self.timex=None

另外在PerpetualCalendar.py增加代码

from DateCalc import *
import re
import time
import sxtwl
import datetime


def getDateInfo():
    print("dddddddddd")
    year,month,day = time.localtime(time.time())[0:3]
    print(str(year)+'-'+str(month)+'-'+str(day))
    wday = datetime.datetime(year,month,day).strftime("%w")
    print(wday)
    wdayx = datetime.datetime(year, month, 27).strftime("%w")
    print(wdayx)
    # ymb, shuoJD = LunarCalendar(year, 0)
    # print(str(ymb)+'-'+str(shuoJD))
    # displayMonth_X(year, month, day)
    ymc = [u"十一", u"十二", u"正", u"二", u"三", u"四", u"五", u"六", u"七", u"八", u"九", u"十"]
    rmc = [u"初一", u"初二", u"初三", u"初四", u"初五", u"初六", u"初七", u"初八", u"初九", u"初十", \
           u"十一", u"十二", u"十三", u"十四", u"十五", u"十六", u"十七", u"十八", u"十九", \
           u"二十", u"廿一", u"廿二", u"廿三", u"廿四", u"廿五", u"廿六", u"廿七", u"廿八", u"廿九", u"三十", u"卅一"]
    lunar = sxtwl.Lunar()
    lunar_day = lunar.getDayBySolar(year,month,day)
    if (lunar_day.Lleap):
        print("阴历(农历):{0}月{1}".format(ymc[lunar_day.Lmc], rmc[lunar_day.Ldi]))
    else:
        print("阴历(农历):{0}月{1}".format(ymc[lunar_day.Lmc], rmc[lunar_day.Ldi]))

    return year,month,day,wday,ymc[lunar_day.Lmc],rmc[lunar_day.Ldi]

通过以上代码就可实现如文章开头的PC端日历界面

三 打包生成EXE

打包命令:pyinstaller -F main.py -w

赋值生成的.exe到桌面
exe文件
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容