Python使用PyQt5实现指定窗口置顶

news2024/12/27 2:43:27

文章目录

  • 前言
  • 一、网上找到的代码
  • 二、尝试与借鉴后的代码——加入PyQt界面
    • 1.引入库
    • 2.主代码
    • 3.完整主代码
    • 4.UI界面代码
  • 总结


前言

工作中,同事随口提了一句:要是能让WPS窗口置顶就好了,老是将窗口切换来切换去的太麻烦了。
然后,这个奇怪的点子引起了本人的注意,那就试试能不能实现吧。


一、网上找到的代码

不知道是不是我手法或版本的缘故,用了网上找的代码都是窗口弹出而已,并没有把它置顶,可以参考以下我尝试过于借鉴得到的成功的博客:
Python中最全的窗口操作,如窗口最大化、最小化、窗口置顶、获取缩放比例等
python选择应用窗口到最前面
Python中设置指定窗口为前台活动窗口(最顶层窗口)win32gui

二、尝试与借鉴后的代码——加入PyQt界面

1.引入库

代码如下(示例):

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
# 下面这个是我使用的ui界面代码
from Window_top import Ui_MainWindow as UI_W

import win32gui
import win32con
import win32com.client
# 下面两行代码是用于解决图标不显示的问题
import ctypes
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")

2.主代码

代码如下(示例):

class MAIN_windows(UI_W, QMainWindow):
    def __init__(self):
        super(MAIN_windows, self).__init__()
        self.hwnd_map = None
        self.setupUi(self)

        self.pushButton.clicked.connect(self.lll)
        self.pushButton_2.clicked.connect(self.Window_top)  # 选择应用窗口置顶
        self.pushButton_3.clicked.connect(self.cancel_Window_top)  # 取消应用窗口置顶

    def get_all_hwnd(self, hwnd, mouse):
        """
        获取后台运行的所有程序
        """
        if (win32gui.IsWindow(hwnd) and
                win32gui.IsWindowEnabled(hwnd) and
                win32gui.IsWindowVisible(hwnd)):
            self.hwnd_map.update({hwnd: win32gui.GetWindowText(hwnd)})

    def lll(self):
        """
        显示获取到的所有程序。
        (第一个显示估计是程序运行的ID号)
        (第二个显示是程序窗口名与程序名)
        """
        try:
            self.hwnd_map = {}
            win32gui.EnumWindows(self.get_all_hwnd, 0)
            for i in self.hwnd_map.items():
                if i[1] != "":
                    print(i)
                    self.textEdit_4.append(str(i[0]) + "    " + str(i[1]))
        except Exception as exx:
            print("\nlll", exx)

    def Window_top(self):
        """
        设置指定窗口置顶
        """
        try:
            App_name = str(self.lineEdit.text())
            for h, t in self.hwnd_map.items():
                if t != "":
                    if t.find(App_name) != -1:
                        # h 为想要放到最前面的窗口句柄
                        print(h, t)

                        win32gui.BringWindowToTop(h)
                        shell = win32com.client.Dispatch("WScript.Shell")
                        shell.SendKeys('%')
                        # 被其他窗口遮挡,调用后放到最前面
                        win32gui.SetWindowPos(h, win32con.HWND_TOPMOST, 0, 0, 800, 600, win32con.SWP_SHOWWINDOW)
                        # 解决被最小化的情况
                        win32gui.ShowWindow(h, win32con.SW_RESTORE)

        except Exception as ee:
            print("\nWindow_top", ee)

    def cancel_Window_top(self):
        """
        取消指定窗口置顶
        """
        try:
            App_name = str(self.lineEdit.text())
            for h, t in self.hwnd_map.items():
                if t != "":
                    if t.find(App_name) != -1:
                        # h 为想要放到最前面的窗口句柄
                        print(h, t)

                        # win32gui.BringWindowToTop(h)
                        # shell = win32com.client.Dispatch("WScript.Shell")
                        # shell.SendKeys('%')
                        # 取消置顶
                        win32gui.SetWindowPos(h, win32con.HWND_NOTOPMOST, 0, 0, 800, 600, win32con.SWP_SHOWWINDOW)
                        # 解决被最小化的情况
                        win32gui.ShowWindow(h, win32con.SW_RESTORE)
        except Exception as ee:
            print("\ncancel_Window_top:", ee)

    def closeEvent(self, event):
        """
        软件关闭时取消所有窗口置顶,
        但还有些问题,开了多个窗口置顶后貌似没能让所有置顶的窗口都取消置顶
        """
        try:
            self.cancel_Window_top()
        except Exception as ee:
            print("\ncloseEvent:", ee)


if __name__ == "__main__":
    try:
        app = QApplication(sys.argv)
        win = MAIN_windows()
        win.show()
        sys.exit(app.exec_())

    except Exception as ex:
        print('主函数入口出错了:', ex)

启动后点击“显示有哪些窗口可以置顶”就会得到类似下图的界面
该处使用的url网络请求的数据。
输入的应用窗口名不需要输全名,输入一些特有的关键字即可,例如打开了Google Chrome,获取到的应用名会包含正在访问的页面标题,显示为“写文章-CSDN博客 - Google Chrome”,那么在输入栏中输入“Google Chrome”或“Google”就行了。
针对WPS软件的话,就直接输入“WPS”即可。


3.完整主代码

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
# 下面这个是我使用的ui界面代码
from Window_top import Ui_MainWindow as UI_W

import win32gui
import win32con
import win32com.client
# 下面两行代码是用于解决图标不显示的问题
import ctypes
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")


class MAIN_windows(UI_W, QMainWindow):
    def __init__(self):
        super(MAIN_windows, self).__init__()
        self.hwnd_map = None
        self.setupUi(self)

        self.pushButton.clicked.connect(self.lll)
        self.pushButton_2.clicked.connect(self.Window_top)  # 选择应用窗口置顶
        self.pushButton_3.clicked.connect(self.cancel_Window_top)  # 取消应用窗口置顶

    def get_all_hwnd(self, hwnd, mouse):
        """
        获取后台运行的所有程序
        """
        if (win32gui.IsWindow(hwnd) and
                win32gui.IsWindowEnabled(hwnd) and
                win32gui.IsWindowVisible(hwnd)):
            self.hwnd_map.update({hwnd: win32gui.GetWindowText(hwnd)})

    def lll(self):
        """
        显示获取到的所有程序。
        (第一个显示估计是程序运行的ID号)
        (第二个显示是程序窗口名与程序名)
        """
        try:
            self.hwnd_map = {}
            win32gui.EnumWindows(self.get_all_hwnd, 0)
            for i in self.hwnd_map.items():
                if i[1] != "":
                    print(i)
                    self.textEdit_4.append(str(i[0]) + "    " + str(i[1]))
        except Exception as exx:
            print("\nlll", exx)

    def Window_top(self):
        """
        设置指定窗口置顶
        """
        try:
            App_name = str(self.lineEdit.text())
            for h, t in self.hwnd_map.items():
                if t != "":
                    if t.find(App_name) != -1:
                        # h 为想要放到最前面的窗口句柄
                        print(h, t)

                        win32gui.BringWindowToTop(h)
                        shell = win32com.client.Dispatch("WScript.Shell")
                        shell.SendKeys('%')
                        # 被其他窗口遮挡,调用后放到最前面
                        win32gui.SetWindowPos(h, win32con.HWND_TOPMOST, 0, 0, 800, 600, win32con.SWP_SHOWWINDOW)
                        # 解决被最小化的情况
                        win32gui.ShowWindow(h, win32con.SW_RESTORE)

        except Exception as ee:
            print("\nWindow_top", ee)

    def cancel_Window_top(self):
        """
        取消指定窗口置顶
        """
        try:
            App_name = str(self.lineEdit.text())
            for h, t in self.hwnd_map.items():
                if t != "":
                    if t.find(App_name) != -1:
                        # h 为想要放到最前面的窗口句柄
                        print(h, t)

                        # win32gui.BringWindowToTop(h)
                        # shell = win32com.client.Dispatch("WScript.Shell")
                        # shell.SendKeys('%')
                        # 取消置顶
                        win32gui.SetWindowPos(h, win32con.HWND_NOTOPMOST, 0, 0, 800, 600, win32con.SWP_SHOWWINDOW)
                        # 解决被最小化的情况
                        win32gui.ShowWindow(h, win32con.SW_RESTORE)
        except Exception as ee:
            print("\ncancel_Window_top:", ee)

    def closeEvent(self, event):
        """
        软件关闭时取消所有窗口置顶,
        但还有些问题,开了多个窗口置顶后貌似没能让所有置顶的窗口都取消置顶
        """
        try:
            self.cancel_Window_top()

        except Exception as ee:
            print("\ncloseEvent:", ee)


if __name__ == "__main__":
    try:
        app = QApplication(sys.argv)
        win = MAIN_windows()
        win.show()
        sys.exit(app.exec_())

    except Exception as ex:
        print('主函数入口出错了:', ex)


4.UI界面代码

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        font = QtGui.QFont()
        font.setPointSize(12)
        MainWindow.setFont(font)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(False)
        font.setWeight(50)
        self.pushButton.setFont(font)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 3)
        self.textEdit_4 = QtWidgets.QTextEdit(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        self.textEdit_4.setFont(font)
        self.textEdit_4.setObjectName("textEdit_4")
        self.gridLayout.addWidget(self.textEdit_4, 1, 0, 1, 3)
        self.label_9 = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(False)
        font.setWeight(50)
        self.label_9.setFont(font)
        self.label_9.setObjectName("label_9")
        self.gridLayout.addWidget(self.label_9, 2, 0, 1, 1)
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(False)
        font.setWeight(50)
        self.lineEdit.setFont(font)
        self.lineEdit.setObjectName("lineEdit")
        self.gridLayout.addWidget(self.lineEdit, 2, 1, 1, 2)
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(False)
        font.setWeight(50)
        self.pushButton_2.setFont(font)
        self.pushButton_2.setObjectName("pushButton_2")
        self.gridLayout.addWidget(self.pushButton_2, 3, 0, 1, 2)
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("楷体")
        font.setPointSize(14)
        font.setBold(False)
        font.setWeight(50)
        self.pushButton_3.setFont(font)
        self.pushButton_3.setObjectName("pushButton_3")
        self.gridLayout.addWidget(self.pushButton_3, 3, 2, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Window_top"))
        self.pushButton.setText(_translate("MainWindow", "显示有哪些窗口可以置顶"))
        self.label_9.setText(_translate("MainWindow", "输入置顶的应用窗口名"))
        self.pushButton_2.setText(_translate("MainWindow", "确定置顶"))
        self.pushButton_3.setText(_translate("MainWindow", "取消置顶"))

总结

代码中还有些小bug,但不怎么影响使用。
当软件关闭的时候,好像没能让所有置顶过的窗口取消置顶,所以最好是点击界面右下角的“取消置顶”,不然很难让那指定的窗口取消置顶。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/421861.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker-compose 安装nginx php mysql phpadmin

一 摘要 本文主要介绍基于docker docker-compose 安装 lnmp 三件套,以及用phpmysadmin 验证下部署可正确。 二 环境信息 2.1 操作系统 [root2023001 ~]# cat /etc/centos-release CentOS Linux release 7.9.2009 (Core) [root2023001 ~]#2.2 docker [root20230…

【opencv】图像数字化——认识OpenCV中的Mat类( 7 访问多通道Mat对象中的值)

7 访问多通道Mat对象中的值 7.1使用成员函数at() #include <opencv2/core/core.hpp> #include<iostream> using namespace std; using namespace cv; int main() {Mat mm (Mat_<Vec3f>(2, 2) << Vec3f(1, 11, 21), Vec3f(2, 12, 32), Vec3f(3, …

C++【深入理解多态】

文章目录一、多态概念与实现&#xff08;1&#xff09;多态的概念&#xff08;2&#xff09;怎么构成多态&#xff08;3&#xff09;虚函数重写的2个例外&#xff08;4&#xff09;经典剖析巩固知识点&#xff08;5&#xff09; override 和 final&#xff08;6&#xff09;小总…

YOLO算法改进指南【初阶改进篇】:2.改进DIoU-NMS,SIoU-NMS,EIoU-NMS,CIoU-NMS,GIoU-NMS

非极大值抑制(Non-maximum Suppression (NMS))的作用简单说就是模型检测出了很多框,我应该留哪些。 本篇将演示如何修改:NMS、Merge-NMS、Soft-NMS、CIoU-NMS、DIoU-NMS、GIoU-NMS、EIoU-NMS、SIoU-NMS 1. NMS过程 NMS过程 For a prediction bounding box B, the model c…

基于JDK11从源码角度剖析可重入锁ReentrantLock的获取锁和解锁

ReentrantLock是可重入的独占锁&#xff0c;同时只能有一个线程可以获取该锁&#xff0c;其他获取该锁的线程会被阻塞而被放入该锁的AQS阻塞队列里面。 ReentrantLock是JUC包提供的显式锁的一个基础实现类&#xff0c;实现了Lock接口。我们先来看下ReentrantLock的类图&#x…

SpringBoot WebSocket服务端创建

引入maven <!--websocket--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>新建WebSocket配置文件 import org.springframework.context.annotatio…

【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式省赛(第一场)客观题及详细题解

题1 解析  编码器&#xff0c;具有编码功能的逻辑电路&#xff0c;能将每一个编码输入信号变换为不同的二进制的代码输出&#xff0c;是一个组合逻辑电路。 答案 ABC 题2 解析   减法计数器的计数值到0时&#xff0c;会产生一个重装载值&#xff0c;此处重载后就会变成111…

改进YOLO系列:CVPR2023最新 PConv |提供 YOLOv5 / YOLOv8 模型 YAML 文件

论文链接:https://arxiv.org/pdf/2303.03667v2.pdf 一、论文介绍 为了设计快速神经网络,许多工作都集中在减少浮点运算(FLOPs)的数量上。然而,作者观察到FLOPs的这种减少不一定会带来延迟的类似程度的减少。这主要源于每秒低浮点运算(FLOPS)效率低下。 为了实现更快的…

buildSrc + gradle插件:多项目共享gradle依赖管理

自定义gradle 插件&#xff0c;配合 buildSrc 形式的组件库版本管理&#xff0c; 用于实现多 project 项目共享一套版本管理信息 前言 随着组件化越来越常见&#xff0c;module数量越来越多&#xff0c;依赖管理的混乱问题大家想必是都遇到过甚至正在经历着。 对于依赖管理的…

iOS - 接入 Live2D

1.安装 Cmake 1.1 从官方下载 https://cmake.org/download/ 下载成功以后,在终端输入 sudo "/Applications/CMake.app/Contents/bin/cmake-gui" --install校验是否成功 cmake --version1.2 从 Homebrew 安装 (这个方法没有成功) brew install cmake如果提示 co…

简单的配置Sawgger+knife4j完成API测试功能

目的&#xff1a;减少postman的使用&#xff0c;以及生成对应的接口文档 1、添加依赖 基于自身spring boot 版本2.7.X 我选择的是&#xff1a; <dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId>…

网络中的一些基本概念

组建网络的重要设备 集线器,交换机(组建局域网,不能跨局域网组建网络),路由器(wifi本质上是无线路由器,路由器的本质的把俩个局域网给连起来) 网络通信的一些基础概念 IP地址 标识了网络设备所在的位置 端口号 标识了一个具体的应用程序 协议 协议是网络通信的概念,约定好…

校园安全AI视频行为分析系统 yolov7

校园安全AI视频行为分析系统以yolov7网络模型算法为核心&#xff0c;校园安全AI视频行为分析算法模型对现场画面中学生打架、异常跌倒、攀爬翻墙、违规闯入、明火烟雾、睡岗离岗、抽烟打电话等行为主动识别预警存档。YOLOv7 在 5 FPS 到 160 FPS 范围内&#xff0c;速度和精度都…

计算机系统-存储器层次结构

本篇不是学习课程时的笔记&#xff0c;是重看这本书时的简记。对于学习本课程的同学&#xff0c;未涉及的内容不代表考试不涉及&#xff0c;部分省略的部分是在该课程的讨论课中学习的(存储器山&#xff0c;矩阵乘法)&#xff0c;对于核心内容的掌握&#xff0c;需要学习相关实…

还在crud?快来学习架构设计啦---微服务下的依赖管理(maven篇)

文章目录一、前言二、实战2.1 创建父工程统一依赖的版本管理2.2 创建公共使用的 common工程2.3 创建子工程并引入父工程的依赖以及公共工程2.4 搭建启动环境2.5 启动程序开始验证三、总结一、前言 2023年口罩放开的第一年&#xff0c;大多数人都是想着重新开始&#xff0c;抓住…

Python assert实现软件测试

PythonPythonPython 对于测试非常看重&#xff0c;例如测试中最常见的操作——断言 assertassertassert&#xff0c;其在 PythonPythonPython 中就是一个关键字而不是一个函数。而在 CCC 语言中&#xff0c;assertassertassert 只是一个普通的函数。从这点也可以看出&#xff0…

TCP套接字编程

文章目录前言一、TCP套接字1.简单认识TCP协议2.listen函数3.accept函数4.通用TCP服务器二、大小写转换服务1.服务端2.客户端三、多进程版本TCP服务器四、多线程版本TCP服务器前言 这篇文章是紧接着上一篇《UDP套接字编程》文章的&#xff0c;里面详细介绍了套接字编程的一些基…

在Vue项目中使用tinymce富文本编辑器

TinyMC编辑器简介 TinyMCE是一款易用、且功能强大的所见即所得的富文本编辑器。跟其他富文本编辑器相比&#xff0c;有着丰富的插件&#xff0c;支持多种语言&#xff0c;能够满足日常的业务需求并且免费。 TinyMCE的优势&#xff1a; 开源可商用&#xff0c;基于LGPL2.1 插…

虚拟机安装 Ubuntu 桌面版

目录 1、下载系统镜像 2、新建虚拟机 3、配置虚拟机 1、下载系统镜像 Ubuntu桌面版最新版本下载地址&#xff1a;Download | Ubuntu 桌面版 Ubuntu桌面版历史版本下载地址&#xff1a;Download | Ubuntu 桌面版&#xff08;历史版本&#xff09; 以下载18.04 版本为例&am…

【三位重建】NeRF原理+代码讲解

文章目录一、技术原理1.概览2.基于神经辐射场&#xff08;Neural Radiance Field&#xff09;的体素渲染算法3.体素渲染算法4.位置信息编码&#xff08;Positional encoding&#xff09;5.多层级体素采样二、代码讲解1.数据读入2.创建nerf1.计算焦距focal与其他设置2.get_embed…