思路
在使用PyQt
或Qt
开发的过程中,我们都知道如何激活窗口,直接调用QWidget
的activateWindow()
方法即可,但一直以来都有一个困扰我的问题,那就是如何人为地在代码上使我们的窗口脱离激活状态,使系统的焦点不落在我们的窗口上。
然而我找了很久都没找到命名类似deactivateWindow()
或者inactivateWindow()
的方法,百度也搜索不到,甚至Bing
和终极大法Google
也只在Stack Overflow
上找到一个未得到解决的提问。
然而就在机缘巧合之下,我发现了能达到解决此问题的方法,坐稳了我要开始了!

思路很简单,既然我们只能有激活窗口这种操作,那我们激活别的窗口不就使主窗口失去激活状态了嘛!

只需要在程序中创建一个看不见、在任务栏上不显示图标按钮的、不接收事件、甚至大小仅为1×1、在屏幕范围外的窗口,那么激活这个“工具人”窗口,不就等于使主窗口失去激活了吗!!!

当然,我认为从根本上解决问题,应该还从Windows
的api
入手,只是我没在网上找到有类似需求的,只能等其他大神来从根本上解决这个问题(但目前我这个方法用着也挺香的哈哈)。
代码
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton
# 看不见的“工具人”窗口类,副窗口
class InvisibleWidget(QWidget):
def __init__(self, fatherWidget):
super().__init__()
# 传入的fatherWidget是主窗口,注意这里主窗口不是副窗口parent
self.fatherWidget = fatherWidget
self.setGeometry(-500, -500, 1, 1)
self.setFixedSize(self.width(), self.height())
# 设置窗口鼠标事件穿透,相当于不接收鼠标事件
self.setAttribute(Qt.WA_TransparentForMouseEvents, True)
# 设置窗口背景透明
self.setAttribute(Qt.WA_TranslucentBackground, True)
# 设置窗口为无边框、在任务栏上不显示图标按钮
self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool)
# 设置透明度,0为全透明
self.setWindowOpacity(0)
# 主窗口类
class MainWin(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("MainWin")
self.setGeometry(400, 300, 400, 500)
# 取消激活按钮
self.inactivateBtn= QPushButton()
self.inactivateBtn.setParent(self)
self.inactivateBtn.setGeometry(20, 20, 40, 30)
# 当按下inactivateBtn按钮时,执行inactivateWindow方法
self.inactivateBtn.clicked.connect(self.inactivateWindow)
# 副窗口
self.invisibleWidget = InvisibleWidget(self)
# self.invisibleWidget.hide()
# 显示主窗口
self.show()
def inactivateWindow(self):
# 激活副窗口
self.invisibleWidget.activateWindow()
if __name__ == '__main__':
# 进入 PyQt5 的 UI 循环
app = QApplication(sys.argv)
# 创建窗口的实例
win = MainWin()
# 退出窗口的条件
sys.exit(app.exec_())