python实现一个桌面小工具,制作一个桌面的便签提醒工具

参考代码:

参考链接:

参考链接:

核心代码

#!/usr/bin/env xdg-open
[Desktop Entry]
Type=Application
Name=Memo
Comment=Memo Launcher
Exec=/usr/bin/env python "/home/ysw/python/pyqt/memo/widget.py"
Icon=/home/ysw/python/pyqt/memo/img/icon.png
Terminal=false
StartupNotify=true

最近发现了一个非常有意思的python小应用,觉得很赞,所以将学习记录一下。

下载之后大概就是这些文件了,出来的效果也很赞。

小图标制作的也很精致,更加觉得非常有意思了,接下来,看一下源码。

源码

环境是windows+py3

所以,这里我们需要建立一个py2.7的虚拟环境,因为我安装了anaconda,所以可以采用conda建立一个虚拟环境

conda create -n python2.7 python=2.7

激活python2.7的虚拟环境

activate python2.7

退出虚拟环境

deactivate

删除虚拟环境

conda remove -n python2.7 --all

根据这个步骤,我就新建了一个名叫python2.7的虚拟环境。

dataAccess.py

# -*- coding:utf8 -*-
#! /usr/bin/python
'''
dictdata = {
        'id': '2012', 
        'datetime': '10',
        'memoList': [
            {
                'id': '1',
                'pid': '2012',
                'content': 'hello',
                'deadline': '2013',
                'finished': True,
                },
            ],
        'notfinish': [],
        }
'''
import os
import json
'''
assume that filename is date.json
memo id is date
the id of each content in memo is number
'''
def save(dictdata):
    '''
    1. judge if exists the file
        yes: write jsondata
        no: new the file and write jsondata
    '''
    filename = dictdata['id'] + '.json'
    f = open(filename, 'w')
    jsondata = json.dumps(dictdata)
    f.write(jsondata)
    f.close
def read(date):
    '''
    1. if exist today's file
        a. judge finish or not and directly load it
    2. not exist
        a. init the today's file
            1. to check log and get lastmemo file
    3. finally, return a unfinished content list
    '''
    contentlist = []
    filename = date + '.json'
    if os.path.exists(filename):
        f = open(filename, 'r')
        jsondata = json.load(f)
        f.close()
        memolist = jsondata['memolist']
        for each in memolist:
            if not each['finished']:
                contentlist.append(each)
    else:
        f = open('log.json', 'r')
        jsondata = json.load(f)
        f.close()
        lastmemo = jsondata['last']
        filename = lastmemo + '.json'
        f = open(filename, 'r')
        jsondata = json.load(f)
        f.close()
        memolist = jsondata['memolist']
        for each in memolist:
            if not each['finished']:
                contentlist.append(each)
    return contentlist
if __name__ == "__main__":
    data = {
        'id': '2012',
        'datetime': '10',
        'memolist': [
            {
                'id': '1',
                'pid': '2012',
                'content': 'hello',
                'deadline': '2013',
                'finished': False,
                },
            {
                'id': '2',
                'pid': '2012',
                'content': 'world',
                'deadline': '2013',
                'finished': False,
                },
            ],
        'notfinish': [],
        }
    save(data)
    r = read(data['id'])

exe.py

from distutils.core import setup
import py2exe
import sys
 
#this allows to run it with a simple double click.
sys.argv.append('py2exe')
 
py2exe_options = {
        "includes": ["sip"],
        "dll_excludes": ["MSVCP90.dll",],
        "compressed": 1,
        "optimize": 2,
        "ascii": 0,
        "bundle_files": 1,
        }
 
window = [{
	"script": "hotkey.pyw",
	'icon_resources': [(1, 'icon2.ico'),]
	}]
setup(
      name = 'PyQt Demo',
      version = '1.0',
      windows = ['hotkey.pyw',], 
      options = {'py2exe': py2exe_options}
      )

myLabel.py

# -*- coding:utf8 -*-
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class FocusEdit(QWidget):
    def __init__(self, parent=None):
        super(FocusEdit, self).__init__(parent)
        self.initObjects()
        self.setObjects()
        self.setStyle()
        self.setMySizePolicy()
        self.connect(self.timeEdit, SIGNAL("dateTimeChanged(QDateTime)"),
                self.setDateTime)
    def initObjects(self):
        self.textEdit = QTextEdit()
        self.timeEdit = QDateTimeEdit()
        self.layout = QHBoxLayout()
    def setObjects(self):
        self.layout.addWidget(self.textEdit)
        self.layout.addWidget(self.timeEdit)
        self.setLayout(self.layout)
    def setMySizePolicy(self):
        self.layout.setContentsMargins(0,0,0,0)
        self.layout.setSpacing(0)
        self.timeEdit.setMinimumHeight(40)
        self.textEdit.setMinimumHeight(40)
        self.textEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.timeEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
    def setStyle(self):
        edit = '''
            QTextEdit{
                border-top-left-radius: 4px;
                border-bottom-left-radius: 4px;
                background-color: #CCCCCC;
                selection-color: #CCCCCC;
                selection-background-color: #222222;
                color: black;
                }
        '''
        time = '''
            QDateTimeEdit{
                background-color: #CCCCCC;
                selection-color: #CCCCCC;
                selection-background-color: #222222;
                color: black;
                }
        '''
        self.textEdit.setStyleSheet(edit)
        self.timeEdit.setStyleSheet(time)
    def setText(self, text):
        self.textEdit.setText(text)
    def setDateTime(self, datetime):
        self.timeEdit.setDateTime(datetime)
    def setTimeFromText(self, text):
        datetime = QDateTime.fromString(text)
        self.timeEdit.setDateTime(datetime)
    def document(self):
        return self.textEdit.document()
    def dateTime(self):
        return self.timeEdit.dateTime()
    def focusInEvent(self, event):
        self.emit(SIGNAL("Editing"))
    def focusOutEvent(self, event):
        if event.reason() == 4: # popup focus
            event.ignore()
        if self.textEdit.hasFocus() or self.timeEdit.hasFocus():
            event.ignore()
        else:
            self.emit(SIGNAL("EditFinish"))
    def setFocus(self):
        self.textEdit.setFocus()
    def save(self):
        self.textEdit.setDocument(self.textEdit.document())
        self.timeEdit.setDateTime(self.timeEdit.dateTime())
    def mouseMoveEvent(self, QMouseEvent):
        pass
class NoteLabel(QWidget):
    def __init__(self, memodata=None, parent=None):
        super(NoteLabel, self).__init__(parent)
        self.initObjects()
        self.setObjects(memodata)
        self.setMySizePolicy()
        self.setStyle()
        self.setEffects()
        self.content = memodata
        self.okBtn.clicked.connect(self.ok)
        self.connect(self.contentEdit, SIGNAL("EditFinish"), self.ok)
        self.connect(self.contentEdit, SIGNAL("editing"), self.editing)
        pw = self.parentWidget()
        self.connect(pw, SIGNAL("EditFinish"), self.ok)
    def initObjects(self):
        self.palette = QPalette()
        self.layout = QHBoxLayout()
        self.label = QLabel()
        self.deadlineLabel = QLabel()
        self.contentEdit = FocusEdit()
        self.okBtn = QPushButton(u'确定')
        pix = QPixmap(16, 16)
        pix.fill(Qt.black)
        self.actionTextColor = QAction(QIcon(pix), "&Color", self, \
                triggered=self.textColor)
        self.actionTextFont = QAction(QIcon('./img/font.png'), "&Font", self, \
                triggered=self.textFont)
    def setFirstLabel(self):
        print 'first label'
        self.palette.setColor(self.label.foregroundRole(), Qt.red)
        self.label.setPalette(self.palette)
    def setAllLabel(self, memodata):
        string = memodata['content']
        if string:
            self.label.setText(string)
            self.contentEdit.setText(string)
        else:
            self.label.setText(u'<i>内容为空</i>')
            self.contentEdit.setText(u'内容为空')
        self.deadlineLabel.setText(memodata['deadline'])
        self.contentEdit.setTimeFromText(memodata['deadline'])
    def setObjects(self, memodata):
        self.setAllLabel(memodata)
        self.setPalette(self.palette)
        self.setLabelDefaultFont()
        self.label.setMargin(5)
        self.label.setPalette(self.palette)
        self.label.setWordWrap(True)
        self.palette.setColor(self.label.foregroundRole(), Qt.black)
        self.deadlineLabel.setMargin(10)
        self.deadlineLabel.setPalette(self.palette)
        self.deadlineLabel.setWordWrap(True)
        self.layout.addWidget(self.label)
        self.layout.addSpacing(3)
        self.layout.addSpacing(3)
        self.layout.addWidget(self.deadlineLabel)
        self.layout.addWidget(self.contentEdit)
        self.layout.addWidget(self.okBtn)
        self.layout.setContentsMargins(0,0,0,0)
        self.layout.setSpacing(0)
        self.contentEdit.hide()
        self.okBtn.hide()
        self.setLayout(self.layout)
    def setMySizePolicy(self):
        self.setMinimumWidth(460)
        self.label.setMaximumWidth(300)
        self.label.setMinimumWidth(300)
        self.deadlineLabel.setMinimumWidth(100)
        self.contentEdit.setMinimumHeight(40)
        self.contentEdit.setMaximumHeight(40)
        self.okBtn.setMaximumHeight(40)
        self.okBtn.setMinimumWidth(40)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
    def setLabelDefaultFont(self):
        font = QFont()
        font.setFamily('Microsoft YaHei')
        font.setPointSize(10)
        self.label.setFont(font)
        self.deadlineLabel.setFont(font)
    def setStyle(self):
        label = '''
            QLabel{
                border-radius: 4px;
                background-color: #CCCCCC;
                }
            QLabel:Hover{
                border: 2px solid #DDDDDD;
                }
        '''
        btn = '''
           QPushButton{
                color: #003300;
                border-top-right-radius: 4px;
                border-bottom-right-radius: 4px;
                background-color: #CCCC99;
                font-size: 15px;
                font-family: '';
                }
            QPushButton:Hover{
                background-color: #009966;
                color: white;
                }
        '''
        self.okBtn.setStyleSheet(btn)
        self.label.setStyleSheet(label)
        self.deadlineLabel.setStyleSheet(label)
    def setEffects(self):
        self.opacity = QGraphicsOpacityEffect()
        self.opacity.setOpacity(0.7)
        self.setGraphicsEffect(self.opacity)
    def changeEffects(self):
        self.opacity = QGraphicsOpacityEffect()
        self.opacity.setOpacity(0.9)
        self.setGraphicsEffect(self.opacity)
    def contextMenuEvent(self, event):
        self.menu = QMenu()
        self.menu.addAction(self.actionTextFont)
        self.menu.addAction(self.actionTextColor)
        self.menu.move(self.cursor().pos())
        self.menu.show()
    def textColor(self):
        currentColor = self.palette.color(QPalette.WindowText)
        color = QColorDialog.getColor(currentColor, self)
        if not color.isValid():
            return
        else:
            self.palette.setColor(self.label.foregroundRole(), color)
            pix = QPixmap(16, 16)
            pix.fill(color)
            self.actionTextColor.setIcon(QIcon(pix))
            self.label.setPalette(self.palette)
    def textFont(self):
        currentFont = self.label.font()
        font = QFontDialog.getFont(currentFont, self)
        if font[1]:
            self.label.setFont(font[0])
            self.deadlineLabel.setFont(font[0])
            self.actionTextFont.setFont(font[0])
    def mouseDoubleClickEvent(self, event):
        self.contentEdit.save()
        if event.button() == Qt.LeftButton:
            self.label.hide()
            self.deadlineLabel.hide()
            self.contentEdit.setText(self.contentEdit.document().toPlainText())
            text = self.deadlineLabel.text()
            self.contentEdit.setTimeFromText(text)
            self.contentEdit.show()
            self.contentEdit.setFocus()
            self.okBtn.show()
            self.emit(SIGNAL('Editing'))
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.dragPos = event.globalPos() - self.pos()
            event.accept()
    def mouseMoveEvent(self, QMouseEvent):
        pw = self.parentWidget() # 获取父widget,也就是本程序中的主widget
        widget1 = pw.getTrashRect() # 获取主widget 的 垃圾箱widget(函数名没有改过来)
        flag = self.isCollide(widget1, self) # 检测两个widget的碰撞
        if flag:
            self.emit(SIGNAL('collideTrash'), True) # 碰撞就发射collideTrash信号
        else:
            self.emit(SIGNAL('collideTrash'), False)
        # 以下代码用于进行widget的拖拽
        if QMouseEvent.buttons() == Qt.LeftButton:
            self.move(QMouseEvent.globalPos() - self.dragPos)
            QMouseEvent.accept()
        if QMouseEvent.buttons() == Qt.RightButton:
            QMouseEvent.ignore()
    def mouseReleaseEvent(self, QMouseEvent):
        # 拖拽动作完成之后检测是否碰撞以确定该widget是否被删除
        pw = self.parentWidget()
        widget1 = pw.getTrashRect()
        flag = self.isCollide(widget1, self)
        if flag:
            self.emit(SIGNAL('collideTrash'), True)
            self.content['finished'] = True
            self.emit(SIGNAL('OneMemoFinish'), self.content['content'])
            print "emit meomofinish"
            self.hide()
        else:
            self.emit(SIGNAL('collideTrash'), False)
            self.hide()
            self.show()
    def enterEvent(self, event):
        self.changeEffects()
        pass
    def leaveEvent(self, event):
        self.setEffects()
        pass
    def setText(self, string):
        self.label.setText(string)
    def ok(self):
        text = self.contentEdit.document()
        self.content['content'] = unicode(text.toPlainText())
        self.label.setText(text.toPlainText())
        datetime = self.contentEdit.dateTime().toString()
        self.content['deadline'] = unicode(datetime)
        self.okBtn.hide()
        self.contentEdit.hide()
        self.label.show()
        self.deadlineLabel.setText(datetime)
        self.deadlineLabel.show()
        self.editFinish() # it will emit signal to let parent know
    def editFinish(self):
        self.emit(SIGNAL("EditFinish"))
    def editing(self):
        self.emit(SIGNAL("Editing"))
    def isCollide(self, widget1, widget2):
        dict1 = {}
        dict1['size'] = widget1.size()
        dict1['pos'] = widget1.pos()
        dict2 = {}
        dict2['size'] = widget2.size()
        dict2['pos'] = widget2.pos()
        r1TopRightX = dict1['pos'].x() + dict1['size'].width()
        r1TopRightY = dict1['pos'].y()
        r1BottomLeftX = dict1['pos'].x()
        r1BottomLeftY = dict1['pos'].y() + dict1['size'].height()
        r2TopRightX = dict2['pos'].x() + dict2['size'].width()
        r2TopRightY = dict2['pos'].y()
        r2BottomLeftX = dict2['pos'].x()
        r2BottomLeftY = dict2['pos'].y() + dict2['size'].height()
        if r1TopRightX > r2BottomLeftX and r1TopRightY < r2BottomLeftY \
                and r2TopRightX > r1BottomLeftX and r2TopRightY < r1BottomLeftY:
                    return True
        else:
            return False
    def setLabelNormalStyle(self):
        normal = '''
            QLabel{
                border-radius: 4px;
                background-color: #CCCCCC;
                }
            QLabel:Hover{
                border: 2px solid #DDDDDD;
                }
        '''
        self.label.setStyleSheet(normal)
    def changeLabelStyleToCollide(self):
        hover = '''
            QLabel{
                border-radius: 4px;
                background-color: #009966;
                border: 2px solid #DDDDDD;
                }
        '''
        self.label.setStyleSheet(hover)
    def getContent(self):
        return self.content

myMenu.py

# -*- coding:utf8 -*-
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class EffectLabel(QLabel):
    def __init__(self, parent=None):
        super(EffectLabel, self).__init__(parent)
        self.opacity = QGraphicsOpacityEffect()
        self.setEffects()
    def enterEvent(self, event):
        self.changeEffects()
    def leaveEvent(self, event):
        self.setEffects()
    def setEffects(self):
        self.opacity.setOpacity(0.5)
        self.setGraphicsEffect(self.opacity)
    def changeEffects(self):
        self.opacity.setOpacity(0.9)
        self.setGraphicsEffect(self.opacity)
    
class EffectButton(QPushButton):
    def __init__(self, parent=None):
        super(EffectButton, self).__init__(parent)
        self.opacity = QGraphicsOpacityEffect()
        self.setEffects()
    
    def enterEvent(self, event):
        self.changeEffects()
    
    def leaveEvent(self, event):
        self.setEffects()
    def setEffects(self):
        self.opacity.setOpacity(0.5)
        self.setGraphicsEffect(self.opacity)
    def changeEffects(self):
        self.opacity.setOpacity(0.9)
        self.setGraphicsEffect(self.opacity)
    def mouseMoveEvent(self, event):
        pass
class MainMenu(QWidget):
    def __init__(self, parent=None):
        super(MainMenu, self).__init__(parent)
        self.initObjects()
        self.setObjects()
        self.setTrashStyle()
        self.setMyStyle()
        self.setMySize()
        pw = self.parentWidget()
        self.addBtn.clicked.connect(self.addBtnClicked)
    def initObjects(self):
        self.trashOpacity = QGraphicsOpacityEffect()
        self.opacity = QGraphicsOpacityEffect()
        self.addBtn = EffectButton()
        self.trashLabel= EffectLabel()
        self.layout = QVBoxLayout()
    def setObjects(self):
        self.layout.addWidget(self.addBtn)
        self.layout.addStretch(1)
        self.layout.addWidget(self.trashLabel)
        self.layout.setContentsMargins(0,0,0,0)
        self.setLayout(self.layout)
    def setMySize(self):
        self.trashLabel.setMaximumSize(48, 48)
        self.trashLabel.setMinimumSize(48, 48)
        self.addBtn.setMaximumSize(48, 48)
        self.addBtn.setMinimumSize(48, 48)
    
    def setMyStyle(self):
        add = '''
            QPushButton{
                border-radius: 4px;
                background-image: url('./img/add2.png');
                }
            QPushButton:Pressed{
                background-image: url('./img/addHover.png');
                }
        '''
        self.addBtn.setStyleSheet(add)
        
    def setTrashStyle(self):
        trash = '''
            QLabel{
                border-radius: 4px ;
                background-image: url('./img/trash.png');
                }
            QLabel:Hover{
                background-image: url('./img/trashHover.png');
                }
        '''
        self.trashLabel.setStyleSheet(trash)
        self.trashLabel.setEffects()
    
    def setMySelfStyle(self):
        style = '''
            QWidget{
                background-color: #DDDDDD;
                }
        '''
        self.setStyleSheet(style)
    def getTrashPosSize(self):
        return self.trashLabel
    
    def changeTrashStyleToHover(self):
        trash = '''
            QLabel{
                border-radius: 4px ;
                background-image: url('./img/trashHover.png');
                }
        '''
        self.trashLabel.setStyleSheet(trash)
        self.trashLabel.changeEffects()
    
    def addBtnClicked(self):
        self.emit(SIGNAL("add"))

trayIcon.py

# -*- coding:utf8 -*-
import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class TrayIcon(QSystemTrayIcon):
    def __init__(self, parent=None):
        super(TrayIcon, self).__init__(parent)
        self.initObjects()
        self.setObjects()
        self.activated.connect(self.iconClicked)
    def initObjects(self):
        self.menu = QMenu()
        self.showAction = QAction(u'显示', self, triggered=self.showWidget)
        self.quitAction = QAction(u"退出", self, triggered=self.exitApp)
        self.icon = QIcon('./img/icon.png')
    def setObjects(self):
        self.menu.addAction(self.showAction)
        self.menu.addAction(self.quitAction)
        self.setIcon(self.icon)
        self.setContextMenu(self.menu)
    def iconClicked(self, reason):
        print reason
        if reason==2 or reason==3:
            pw = self.parent()
            if pw.isVisible():
                pw.hide()
            else:
                pw.show()
    def exitApp(self):
        self.setVisible(False)
        self.parent().exit()
        qApp.quit()
        sys.exit()
    def showWidget(self):
        self.emit(SIGNAL("showMain"))
if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    ti = TrayIcon()
    ti.show()
    sys.exit(app.exec_())

widget.py

#!/usr/bin/python
# -*- coding:utf8 -*-
import os
import json
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from myLabel import NoteLabel
from myMenu import MainMenu
from trayIcon import TrayIcon
import dataAccess
class mainUi(QWidget):
    def __init__(self, parent=None):
        super(mainUi, self).__init__(parent)
        self.initObjects()
        self.setObjects()
        self.setEffects()
        self.initProgram()
        self.connect(self.mainMenu, SIGNAL("add"), self.addNewNoteLabel)
        self.connect(self.trayIcon, SIGNAL("show"), self.show)
        self.connect(self.timer, SIGNAL("timeout()"), self.deadlineCome)
        self.connect(self.trayIcon, SIGNAL("showMain"), self.myShow)
    def initObjects(self):
        self.timer = QTimer()
        self.firstMemo = {}
        self.trayIcon = TrayIcon()
        self.isEditing = False
        self.leftLayout = QVBoxLayout()
        self.centerLayout = QVBoxLayout()
        self.mainMenu = MainMenu()
        self.layout = QHBoxLayout()
    def setObjects(self):
        self.trayIcon.show()
        # selfSize = QSize(600, 370)
        # deskRect = self.getDeskSize()
        # selfPoint = QPoint()
        # selfPoint.setX(deskRect.center().x() - selfSize.width()/2)
        # selfPoint.setY(deskRect.center().y() - selfSize.height()/2)
        # self.setGeometry(QRect(selfPoint, selfSize))
        # self.setMaximumSize(568,370)
        self.setMinimumWidth(550)
        self.setMaximumWidth(600)
        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.leftLayout.addWidget(self.mainMenu)
        self.layout.addStretch(1)
        self.layout.addLayout(self.leftLayout)
        self.layout.addSpacing(10)
        self.layout.addLayout(self.centerLayout)
        self.setLayout(self.layout)
        self.setWindowIcon(QIcon('./img/icon.png'))
        self.trayIcon.setParent(self)
        self.setWindowTitle("memo")
    def initLabel(self, date):
        memolist = dataAccess.read(date)
        datetime = QDateTime.currentDateTime()
        date = QDate.currentDate()
        if len(memolist):
            self.firstMemo = memolist[0]
            for each in memolist:
                self.addLabel(each)
            self.setFirstMemo()
            self.deadlineReady()
    def deadlineReady(self):
        '''
        when the deadline is changed or seted, this function should be called;
        it calculate the interval between the deadline and the currenttime;
        '''
        self.timer.stop()
        datetime = QDateTime.currentDateTime()
        interval = QDateTime.fromString(self.firstMemo['deadline']).msecsTo(datetime)
        if interval <= 0:
            self.timer.setInterval(-interval)
            self.timer.start()
        else:
            self.deadlineCome()
            self.timer.stop()
            self.timer.setInterval(600000)
            self.timer.start()
    def initProgram(self):
        date = QDate.currentDate().toString()
        if os.path.exists('log.json'):
            self.initLabel(unicode(date))
            dictdata = {}
            dictdata['last'] = unicode(date)
            jsondata = json.dumps(dictdata)
            f = open('log.json', 'w')
            f.write(jsondata)
            f.close()
        else:
            ' first run the program '
            dictdata = {}
            dictdata['last'] = unicode(date)
            jsondata = json.dumps(dictdata)
            f = open('log.json', 'w')
            f.write(jsondata)
            f.close()
    def setEffects(self):
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setFocusPolicy(Qt.StrongFocus)
    def addLabel(self, data):
        label = NoteLabel(data, self)
        self.connect(label, SIGNAL("collideTrash"), \
                self.trashHover)
        self.connect(label, SIGNAL("Editing"), self.editing)
        self.connect(label, SIGNAL("EditFinish"), self.editFinish)
        self.connect(label, SIGNAL("OneMemoFinish"), self.oneMemoFinish)
        allCount = self.centerLayout.count()
        if allCount == 0:
            self.centerLayout.addWidget(label)
        else:
            self.centerLayout.insertWidget(allCount-1, label)
    def addNewNoteLabel(self):
        date = QDate.currentDate().toString()
        datetime = QDateTime.currentDateTime().toString()
        allCount = self.centerLayout.count()
        content = {
                'id': allCount-1,
                'content': u'主人,双击我可以进行编辑,右键可以进行个性化设置O(∩_∩)O哈!',
                'deadline': unicode(datetime),
                'pid': unicode(date),
                'finished': False,
                }
        label = NoteLabel(content, self)
        self.connect(label, SIGNAL("collideTrash"), \
                self.trashHover)
        self.connect(label, SIGNAL("Editing"), self.editing)
        self.connect(label, SIGNAL("EditFinish"), self.editFinish)
        self.connect(label, SIGNAL("OneMemoFinish"), self.oneMemoFinish)
        self.centerLayout.insertWidget(allCount-1, label)
        self.setFirstMemo()
#        self.deadlineReady()
    def getData(self):
        date = QDate.currentDate().toString()
        memolist = []
        # while self.centerLayout.count():
        for i in range(self.centerLayout.count()):
            item = self.centerLayout.itemAt(i)
            try:
                w = item.widget()
                if w:
                    c = w.getContent()
                    memolist.append(c)
            except Exception, e:
                pass
        data = {}
        data['id'] = unicode(date)
        data['memolist'] = memolist
        return data
    def getDeskSize(self):
        rect = QApplication.desktop().availableGeometry()
        return rect
    def getTrashRect(self):
        return self.mainMenu.getTrashPosSize()
    def trashHover(self, flag):
        if flag:
            self.mainMenu.changeTrashStyleToHover()
        else:
            self.mainMenu.setTrashStyle()
    def editFinish(self):
        self.setFirstMemo()
        self.deadlineReady()
        self.isEditing = False
    def editing(self):
        self.isEditing = True
    def myHide(self):
        if self.isEditing:
            pass
        else:
            self.hide()
    def myShow(self):
        if not self.isVisible():
            self.show()
        self.setWindowsFlags(Qt.WindowStaysOnTopHint)
    def enterEvent(self, event):
        self.mainMenu.show()
    def leaveEvent(self, event):
        if self.centerLayout.count() != 0:
            self.mainMenu.close()
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.dragPos = event.globalPos() - self.pos()
        if self.isEditing:
            self.emit(SIGNAL("EditFinish")) # label will catch this signal and ok 
        event.accept()
    def mouseMoveEvent(self, QMouseEvent):
        # 以下代码用于进行widget的拖拽
        if QMouseEvent.buttons() == Qt.LeftButton:
            self.move(QMouseEvent.globalPos() - self.dragPos)
            QMouseEvent.accept()
        if QMouseEvent.buttons() == Qt.RightButton:
            QMouseEvent.ignore()
    def exit(self):
        data = self.getData()
        dataAccess.save(data)
        self.close()
    def closeEvent(self, event):
        data = self.getData()
        dataAccess.save(data)
        self.hide()
        event.ignore()
        self.trayIcon.showMessage(u"提示",
                u'程序已最小化到托盘,点击托盘可以进行操作')
    def compareTime(self, memo1, memo2):
        time1 = QDateTime.fromString(memo1['deadline'])
        time2 = QDateTime.fromString(memo2['deadline'])
        if time1.secsTo(time2) > 0: # time1 < time2
            return memo1
        else:
            return memo2
    def deadlineCome(self):
        self.trayIcon.showMessage(u"最后期限已到", self.firstMemo['content']\
                + '\n\n' + u'10分钟后将进行下次提醒')
    def setFirstMemo(self):
        data = self.getData()
        memolist = data['memolist']
        for each in memolist:
            if not each['finished']:
                if not self.firstMemo.has_key('deadline'):
                    self.firstMemo = each
                else:
                    if self.firstMemo['finished']:
                        self.firstMemo = each
                    self.firstMemo = self.compareTime(self.firstMemo, each)
        for i in range(self.centerLayout.count()):
            item = self.centerLayout.itemAt(i)
            try:
                w = item.widget()
                if w:
                    c = w.getContent()
                    if c == self.firstMemo:
                        w.setFirstLabel()
            except Exception, e:
                print "get label widget error"
        self.trayIcon.showMessage(u'你最先需要完成', \
                self.firstMemo['deadline']+'\n'+self.firstMemo['content'])
    def oneMemoFinish(self, string):
        print "memo receive"
        self.trayIcon.showMessage(u'下面任务已完成', string)
        self.setFirstMemo()
        self.deadlineReady()
class mainWidget(QWidget):
    def __init__(self, parent=None):
        super(mainWidget, self).__init__(parent)
        self.initObjects()
        self.setObjects()
        self.m.show()
    def initObjects(self):
        self.m = mainUi()
        self.layout = QHBoxLayout()
    def setObjects(self):
        deskRect = self.getDeskSize()
        selfPoint = QPoint()
        selfPoint.setX(deskRect.center().x() - selfSize.width()/2)
        selfPoint.setY(deskRect.center().y() - selfSize.height()/2)
        self.setGeometry(QRect(selfPoint, selfSize))
        point = QPoint(0,0)
        self.setWindowOpacity(0.5)
        self.layout.addWidget(self.m)
        self.setLayout(self.layout)
    def getDeskSize(self):
        rect = QApplication.desktop().availableGeometry()
        return rect
if __name__ == "__main__":
    import sys
    currentPath = sys.path[0]
    print currentPath
    os.chdir(currentPath)
    app = QApplication(sys.argv)
    w = mainUi()
    w.move(QApplication.desktop().width(), 0)
    w.show()
    sys.exit(app.exec_())

出现的问题

pip install py2exe