标签:des style http io os 使用 java ar 文件
- 一直都有做一个笔记软件的想法,而我给笔记软件设计的一个特色功能就是它的便签功能。不过由于各种原因,笔记软件无法完成,但是他的便签功能也可以脱离笔记单独存在。不过功能也随着有着相应的变化
- 我们可能每天都需要一个计划表来帮助我们更加高效的工作,在windows上我们可能会使用它自带的便签软件,也有一些其他的改进版,但是我认为他们不够友好。于是我非常期待一个功能出色的便签。(我自己写的这个也只能说是个雏形,需要以后进行加工)
- 我和几个同学交流过,从用户角度上讲,一个便签首先要简易,其中操作需要简单,界面不需要花哨,要实用。
添加、删除、修改和编辑“事件”,托盘图标,windows全局快捷键(已实现)
闹钟提醒功能 (未实现)
对于“事件”的保存 (关机重启之后仍然可以显示之前的未完成“事件”)(未实现)
桌面浮动提醒,界面的动画交互 … 等 (未实现)
对于这些功能,也不是要单单的实现这些功能,我们可以通过一些手段让这些普通的功能更加受用户的喜爱,比如说:闹钟提示:你可以添加一个贴心的小功能进去,当是、用户使用电脑时间过久,便签自动进行一些人性化的提醒之类。(这只是功能发散的一个方向)

widget.py: 程序运行入口,主界面的实现https://github.com/zjuysw/memo.git
>如果没有使用过软件,可能对下面的代码注释会有点不理解
- 主界面采用HBoxLayout,其中包含两个VBoxLayout。(实现起来没什么困难)
主界面设置背景图片: 采用QPalette。注:使用stylesheet会让子widget继承。(widget.py)
backImg = QPixmap(‘./img/1.png‘).scaled(self.size()) palette = QPalette() palette.setBrush(self.backgroundRole(), QBrush(backImg)) self.setPalette(palette)
图标的背景图片和样式:采用stylesheet
特效(透明):采用QGraphicsOpacityEffect (mylable.py)
self.opacity = QGraphicsOpacityEffect() self.opacity.setOpacity(0.7) self.setGraphicsEffect(self.opacity)
主要是重写widget的鼠标事件 (mylable.py)
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:
print "yes"
self.emit(SIGNAL(‘collideTrash‘), False)
self.hide()
self.destroy()
else:
self.emit(SIGNAL(‘collideTrash‘), False)
self.hide()
self.show() 下面的代码大概表示了这个技术的核心内容(实际运用请看项目完整代码中的运用)
parentWidget = QWidget()
subWidget = QWidget(parentWidget)
subWidget.emit(SIGNAL("sub"))
parentWidget.connect(subWidget, SIGNAL("sub"), parentWidget.doSomething) 思路:一个layout中包含两个layout,其中layout各自包含2个widget,分别是:内容lable,时间lable,编辑框textedit和确定按钮button。要显示的时候,我们让编辑框和按钮隐藏,编辑的时候,我们让内容和时间隐藏。(mylable.py)
def mouseDoubleClickEvent(self, event):
if event.button() == Qt.LeftButton:
self.label.hide()
self.timeLabel.hide()
self.textEdit.show()
self.textEdit.setFocus()
self.textEdit.setText(self.label.text())
self.okBtn.show() 思路:假设垃圾桶为widget1,我们的显示lable是widget2,由于刚开始的时候垃圾桶在显示lable的左下角,所以他们如果碰撞(重叠)就必然会有:widget2的右上角在widget1的左下角的右上方,widget2的左下角必定在widget1的右上角的左下方
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 直接运用QTextEdit的QFocusEvent (mylable.py)
def focusInEvent(self, event):
print "edit"
self.emit(SIGNAL("Editing"))
def focusOutEvent(self, event):
if event.reason() == 4: # popup focus
event.ignore()
else:
self.emit(SIGNAL("EditFinish")) 使用python的ctypes模块(Qt本身没有相应全局快捷键处理类)(hotkey.py)
#!/usr/bin/env python
# -*- coding: utf8-*-
import sys
import time
from ctypes import *
from ctypes.wintypes import *
from PyQt4.QtGui import QApplication
import widget
delta = 0.3
lastTime = 0
WM_HOTKEY = 0x0312
MOD_ALT = 0x0001
MOD_CONTROL = 0x0002
MOD_SHIFT = 0x0004
WM_KEYUP = 0x0101
class MSG(Structure):
_fields_ = [(‘hwnd‘, c_int),
(‘message‘, c_uint),
(‘wParam‘, c_int),
(‘lParam‘, c_int),
(‘time‘, c_int),
(‘pt‘, POINT)]
key = 192 # ~ key
hotkeyId = 1
if not windll.user32.RegisterHotKey(None, hotkeyId, None, key):
sys.exit("Cant Register Hotkey")
msg = MSG()
app = QApplication(sys.argv)
w = widget.mainUi()
while True:
if (windll.user32.GetMessageA(byref(msg), None, 0, 0) != 0):
if msg.message == WM_HOTKEY and msg.wParam == hotkeyId:
if (time.time() - lastTime) < delta:
w.show()
else:
pass
lastTime = time.time()
if msg.message == WM_KEYUP:
print "up"
w.myHide()
windll.user32.TranslateMessage(byref(msg))
windll.user32.DispatchMessageA(byref(msg)) 基本上看看PyQt的文档差不多了(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.quitAction = QAction(u"退出", self, triggered=self.exitApp)
self.icon = QIcon(‘./img/icon.png‘)
def setObjects(self):
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)
qApp.quit()
sys.exit()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
ti = TrayIcon()
ti.show()
sys.exit(app.exec_()) 好像自己编写的过程中遇到的比较难的技术问题就这些,不过关键还是要把PyQt的一些基础知识学牢固,自己组织软件的时候把需求想清楚,把软件的结构理清楚。欢迎_交流_与_指正_或者_提出更好的方法和建议_。思维的碰撞总会有意想不到的惊喜
标签:des style http io os 使用 java ar 文件
原文地址:http://my.oschina.net/zjuysw/blog/318352