python物体跟着鼠标走_用Python写一个跟随鼠标运动的自定义窗口

背景:因为项目需要,要开发一个在PC上运行的应用程序,生成一个跟随鼠标运动的窗口,并且监听鼠标的点击事件,并在窗口上做相应的显示。

平台:Win7 64位 + Python27 64位

支持库:PyHook + PyQt5

模块的安装这里就不多说了,网上有很多。需要注意的是,PyHook对Python3的支持不是很好,会出现卡死的问题, 还有PyQt5貌似只支持64位。废话不多说了,开始造~

第一步:

先用PyQt5生成一个自定义的窗口:

1 #!usr/bin/env python

2 #-*- coding:utf-8 -*-

3

4 importsys5 from PyQt5.QtCore import *

6 from PyQt5.QtGui import *

7 from PyQt5.QtWidgets import *

8

9 classnewWindow(QWidget):10 def __init__(self, parent=None):11 super(newWindow, self).__init__(parent)12 self.mypix()13 self.setWindowFlags(Qt.FramelessWindowHint) #去除界面边框

14 self.setWindowFlags(Qt.WindowStaysOnTopHint)#窗口显示在屏幕最上方

15 self.setAttribute(Qt.WA_TranslucentBackground)#背景透明

16

17 #显示不规则图片

18 defmypix(self):19 self.update()20 self.pix=QPixmap('./1.png','0',Qt.AvoidDither|Qt.ThresholdAlphaDither|Qt.ThresholdDither)21 self.resize(self.pix.size())22 self.setMask(self.pix.mask())23

24 defpaintEvent(self, QPaintEvent):25 painter=QPainter(self)26 painter.drawPixmap(0,0,self.pix.width(),self.pix.height(),self.pix)27

28 if __name__=="__main__":29 app =QApplication(sys.argv)30

31 w =newWindow()32 w.setWindowTitle('一个窗口')33 w.show()34

35 sys.exit(app.exec_())

显示效果如下:

1004312-20181030120500036-818189868.png

窗口出来了,下一步救赎让它跟随着鼠标进行移动了

第二步 监听鼠标事件

1 #!usr/bin/env python

2 #-*- coding:utf-8 -*-

3

4 importpyHook5 importpythoncom6

7 classMouseListener():8

9 def __init__(self):10

11 #新建钩子管理器

12 hookmanager =pyHook.HookManager()13 #注册动作回调函数

14 hookmanager.MouseLeftDown =self.onMouseLeftDown15 hookmanager.MouseLeftUp =self.onMouseRelease16 hookmanager.MouseMiddleDown =self.onMouseMiddleDown17 hookmanager.MouseMiddleUp =self.onMouseRelease18 hookmanager.MouseRightDown =self.onMouseRightDown19 hookmanager.MouseRightUp =self.onMouseRelease20 hookmanager.MouseMove =self.onMouseMove21 #钩取鼠标事件

22 hookmanager.HookMouse()23 #推送window事件消息

24 pythoncom.PumpMessages()25

26

27

28 defonMouseLeftDown(self, event):29 print("MouseLeft Down!")30

31 returnTrue32

33 defonMouseMiddleDown(self, event):34 print("MouseMiddle Down!")35

36 returnTrue37

38 defonMouseRightDown(self, event):39 print("MouseRight Down!")40

41 returnTrue42

43 defonMouseRelease(self, event):44 print("Button release!")45

46 returnTrue47

48 defonMouseMove(self, event):49 print("Mouse Move!")50

51 returnTrue52

53

54 if __name__=="__main__":55 mouseListener = MouseListener()

结果如下:

1004312-20181030123339175-59988151.png

现在最后的问题就是如何结合这两个程序了。

因为Qt界面本身是一个死循环,而监听器里的pythoncom.PumpMessage()也是一个死循环。很自然的想法就是开启多线程。

开启多线程会出现两个问题: 1、因为是死循环,关闭窗口之后,子线程还是在运行,无法关闭。正常手段无法关闭,只能强制关闭,

但是还是会出现问题。

2、可能是两个死循环有影响的原因,当鼠标移动到窗口的时候会卡死。

感兴趣的可以试试,代码就不贴了,下面的写解决办法。

绞尽脑汁,头发都掉了一斤还是解决不了!无意中发现去掉pythoncom.PumpMessages()这个语句,程序居然可以运行。哈哈,天不绝我!!!^-^

1 #!usr/bin/env python

2 #-*- coding:utf-8 -*-

3

4 importpyHook5 importpythoncom6

7 importsys8 from PyQt5.QtCore import *

9 from PyQt5.QtGui import *

10 from PyQt5.QtWidgets import *

11

12

13 classnewWindow(QWidget):14 def __init__(self, parent=None):15 super(newWindow, self).__init__(parent)16 self.mypix()17 self.setWindowFlags(Qt.FramelessWindowHint) #去除界面边框

18 self.setWindowFlags(Qt.WindowStaysOnTopHint)#窗口显示在屏幕最上方

19 self.setAttribute(Qt.WA_TranslucentBackground)#背景透明

20 #新建钩子管理器

21 self.hookmanager =pyHook.HookManager()22 self.hookmanager.MouseMove =self.onMouseMove23 #钩取鼠标事件

24 self.hookmanager.HookMouse()25

26 #显示不规则图片

27 defmypix(self):28 self.update()29 self.pix=QPixmap('./1.png','0',Qt.AvoidDither|Qt.ThresholdAlphaDither|Qt.ThresholdDither)30 self.resize(self.pix.size())31 self.setMask(self.pix.mask())32

33 defpaintEvent(self, QPaintEvent):34 painter=QPainter(self)35 painter.drawPixmap(0,0,self.pix.width(),self.pix.height(),self.pix)36

37

38 defcloseEvent(self, QEvent):39 self.hookmanager.UnhookMouse()40 sys.exit()41

42 defonMouseMove(self, event):43 #print("Mouse Move!")

44 (x, y) =event.Position45 self.move(x, y)46 returnTrue47

48

49 if __name__=="__main__":50 app =QApplication(sys.argv)51

52 w =newWindow()53 w.setWindowTitle('一个窗口')54 w.show()55

56 sys.exit(app.exec_())

OK,问题解决了,解释这么简单!(PS: 我的IDLE运行,关闭时会出现Runtime Error! 直接用命令行运行就不会出现这个问题了)

总结:猜测可能是Qt界面本身就是有类似于pythoncom.PumpMessages()这样功能的语句,所以前面会出现鼠标移动到界面上就出现卡死的现象。

主要还是对底层不太了解,折腾了许久。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值