PyQt5学习记录(6)---实战:监听系统粘贴板并提取时间
2017-08-05 22:29
555 查看
背景
本文基于PyQt5,监听系统的粘贴板。当拷贝文件时,将路径提取出来显示到界面上。当黏贴的内容和文件中含有时间戳时,将其提取出来。利用这种方式解决选择某类文件只能通过浏览文件系统这种笨重方式效率不高,也不方便的问题。文中的方案在Windows平台正常,但在Mac上当复制PyQt应用程序内时监听有效,当复制其他应用程序里的内容时监听无效,这可能和Mac的沙盒模型有关系。下面先上源码,一共包含三个文件,main文件是入口。源码
main.py
# coding=utf-8 import sys import time from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit, QDockWidget, QListWidget from PyQt5.QtCore import Qt from PyQt5.QtGui import QClipboard from widgets import MainWidget import Utils class MainWindow(QMainWindow): def __init__(self): super().__init__() self.init() self.addClipbordListener() def addClipbordListener(self): clipboard = QApplication.clipboard() clipboard.dataChanged.connect(self.widget.onClipboradChanged) def init(self): self.text = QTextEdit('主窗口') self.widget = MainWidget() self.setCentralWidget(self.widget) self.setGeometry(200, 200, 800, 400) self.setWindowTitle('监听粘贴板') self.show() def main(): app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec_()) def test(): timestramp = Utils.extractTime('2017-6-12 12:24:56') times = time.localtime(timestramp) now_time = time.strftime("%Y-%m-%d %H:%M:%S", times) print(now_time) # 入口 if __name__ == '__main__': test()
Utils.py
# coding=utf-8 import time import os import re def isPng(path): return str(path).endswith('.png') or str(path).endswith('.PNG') def isVideo(path): return str(path).endswith('.mp4') def isAllowConvert2Time(path): return isPng(path) or isVideo(path) def fileName(path): return os.path.basename(path) def extractTimeFromFile(path): name = fileName(path) return extractTime(name) def extractTime(content): timestr = '' timeformat = '' patterns = [r'(\d{8}[-]\d{6})', r'(\d{8}[_]\d{6})', r'(\d{4}-\d{1,2}-\d{2}\s\d{2}:\d{2}:\d{2})', r'(\d{4}/\d{1,2}/\d{2}\s\d{2}:\d{2}:\d{2})'] formats = ['%Y%m%d-%H%M%S', '%Y%m%d_%H%M%S', '%Y-%m-%d %H:%M:%S', '%Y/%m/%d %H:%M:%S'] pf = zip(patterns, formats) for (p, f) in pf: mat = re.search(p, content) if mat: timestr = mat.group() timeformat = f break if timestr and timeformat: timeArray = time.strptime(timestr, timeformat) timestamp = time.mktime(timeArray) # 转出来的单位是秒 print(timestamp) return timestamp else: return -1 # 把秒时间戳转字符串时间 def convertSeconds2TimeStr(timestamp): times = time.localtime(timestamp) timestr = time.strftime("%Y-%m-%d %H:%M:%S", times) return timestr
widgets.py
# coding=utf-8 from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit, QDockWidget, QListWidget, QWidget, QLineEdit, QDateTimeEdit, QVBoxLayout, QHBoxLayout \ , QGridLayout, QLabel from PyQt5.QtCore import Qt, QDateTime import Utils import os # 应用程序的主Widget class MainWidget(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): vlayout = QVBoxLayout() grid = QGridLayout() label1 = QLabel('文件路径') self.lineEdit = QLineEdit() label2 = QLabel('时间点') self.dateEdit = QDateTimeEdit() self.dateEdit.setDisplayFormat('yyyy-MM-dd hh:mm:ss') grid.addWidget(label1, 0, 0) grid.addWidget(self.lineEdit, 0, 1, ) grid.addWidget(label2, 1, 0) grid.addWidget(self.dateEdit, 1, 1) vlayout.addLayout(grid) vlayout.addStretch(1) self.setLayout(vlayout) def onClipboradChanged(self): clipboard = QApplication.clipboard() text = clipboard.text() if text: content = str(text) print('onClipboradChanged---' + content + ' len = ' + str(len(content))) if content.startswith('file:///'): path = content.replace('file:///', '') if not os.path.exists(path): return name = Utils.fileName(path) self.lineEdit.setText(path) if Utils.isAllowConvert2Time(name): self.updateDateTimeEdit(filename=name) pass elif len(content) < 50: self.updateDateTimeEdit(content=content) def updateDateTimeEdit(self, filename = '', content = ''): if filename: times = Utils.extractTimeFromFile(filename) elif content: times = Utils.extractTime(content) if times == -1: return timestr = Utils.convertSeconds2TimeStr(times) print(timestr) self.dateEdit.setDateTime(QDateTime.fromString(timestr, 'yyyy-MM-dd hh:mm:ss')) pass
运行效果
源码要点
1.如何监听系统的粘贴板?
在PyQt5里监听系统的粘贴板还是很方便的,尤其是我需要的只是粘贴的文件路径。通过以下代码监听:def addClipbordListener(self): clipboard = QApplication.clipboard() clipboard.dataChanged.connect(self.widget.onClipboradChanged)
这样当粘贴板内容发生变化时,回到到MainWidget的
onClipboradChanged()函数,在这个函数里通过下面:
def onClipboradChanged(self): clipboard = QApplication.clipboard() text = clipboard.text() ...
这样就能获得粘贴的文本内容,当复制的是文件时,这里传来的是
file:\\\开头的完整文件路径。
2.如何提取时间
上面的代码里限定里只有当复制图片和视频时才从文件名里提取时间戳。当复制的是纯文本时,如果字符串不长则提取,否则不提取,避免复制的大段文字让桌面程序一直阻塞在提取时间戳上。具体提取请看
extractTime()函数。由于提取完时间后,还要转成时间戳,和时间的格式紧密相关。因此我写了两个数组用来存正则条件和时间戳格式。通过
zip()函数关联起来,然后遍历。只要能匹配成功,就直接
break掉。支持的时间格式现在有四种,其中前两种是手机截图和录视频时的文件命名方式:
1.
20170802-200825
2.
20170802_200825
3.
2017-08-02 20:08:25
4.
2017/08/02 20:08:25
当然还有其中时间戳格式,需要的话可以模仿然后加上去。需要注意的是,我代码里的正则表达式并不是很严谨,没有限制的太死,只是作个大概的提取够用就行。
3.时间戳如何相互转化?
由于提取出的字符串类型时间格式有很多,所以我统一先将各种形式的字符串转成时间戳。默认的Python转出来的是以秒为单位的,然后将其再转成一个固定的字符串格式的时间,将其设到QDateTimeEdit控件上。字符串转时间戳
通过下面代码:timeArray = time.strptime(timestr, timeformat) timestamp = time.mktime(timeArray) # 转出来的单位是秒
核心是通过
strptime()函数,第一个参数是字符串,第二个参数是时间格式,得到一个元组格式的时间。通过调用
mktime()函数,将时间元组转成时间戳.
时间戳转字符串时间
通过下面代码进行:times = time.localtime(timestamp) timestr = time.strftime("%Y-%m-%d %H:%M:%S", times)
通过
time.localtime()输入的是时间戳,得到的是时间元组。然后通过
strftime()将时间元组转成对应字符串格式。
4.QDateTimeEidt控件使用
使用这个控件是一定要设置显示的格式:setDisplayFormat('yyyy-MM-dd hh:mm:ss')
如果给定字符串时间要设给它通过:
self.dateEdit.setDateTime(QDateTime.fromString(timestr, 'yyyy-MM-dd hh:mm:ss'))即可。
本文系原创,转载请注明作者yanzi1225627
相关文章推荐
- PHP实战-文章发布系统学习记录
- PyQt5学习记录(7)---监听鼠标拖拽事件实现Mac上百度云盘拖拽效果
- 学习咏南BLOG的datasanp 用流下载文件,同时记录WINDOWS系统日志
- j记录学习--python网络爬虫与信息提取
- crontab记录的日志时间与系统时间不一致
- ios学习记录 day38 UI14中级数据持久化(数据库) 上拉加载下拉刷新 打印当前时间
- 深度学习Caffe实战笔记(10)Windows Caffe使用MATLAB接口提取和可视化特征
- 记录 廖雪峰老师 实战 学习到 Day10的bug 以及解决方案
- python学习笔记-记录程序运行时间
- 【C#学习笔记】获得系统时间
- FAT32文件系统学习记录
- POX学习笔记:添加事件监听的方法(POX事件系统后续)
- 工作记录:系统顶端显示的当前时间
- python学习之路(常用系统模块1--时间模块)
- C#提取系统时间问题
- Tensorflow实战学习(四十八)【系统架构,设计理念,编程模型,API,作用域,批标准化,神经元函数优化】
- android BroadcastReceiver ACTION_TIME_TICK 系统时间监听不到
- PyQt5学习记录(2)---QMainWindow菜单栏、状态栏和工具栏
- 通过jna简单实现java后台监听键盘触发修改系统时间
- 基于《Selenium 2自动化测试实战》的学习笔记(11)—— 设置等待时间