GUI視窗 使用滑鼠指標進行定位程式,獲得程式的視窗句柄、視窗類名、視窗標題、執行緒ID、行程ID、行程名稱、行程路徑、CPU用量、執行緒數、視窗定位及滑鼠坐標,并附加五項可操作控制元件,強制置頂、取消置頂、顯示頂部、前置終止、打開檔案所在位置,可顯示定位程式的圖示,
點個贊留個關注吧!!
資料下載:提取碼:n8pk 源代碼及圖片 資料下載 14kb
將紅色框的指標拖到指定程式上,就會獲得屬性值


此程式使用要注意的事項:
使用須知:
1、在軟體內有一個大的圓形圖示,用滑鼠左鍵進行拖拽到指定檔案上會顯示檔案的所有屬性
但不能左鍵一直拖動超過10秒,必須要松開一下在進行拖拽,否則會自動閃退,可能是因為電腦的性能問題導致的
2、軟體內有五個按鍵
強制置頂可以置頂所有視窗,但不要置頂桌面,否則會覆寫你螢屏上所有的軟體界面,只有使用取消置頂才可以取消掉
顯示頂部,僅僅只是將某軟體的界面顯示到最頂層,但不是一直置頂
強制終止會終止一切的子程式,利用的是 程式名稱和PID進行終止的 終止某個程式要謹慎,因為會把子程式也終止掉
3、二維碼
二維碼由博主設計出來,切勿亂改,如有轉載或使用,請標注出處和博主身份
開始我們的程式
匯入程式所需要的模塊,如果沒有模塊的使用 pip install 進行安裝,如果是版本不夠可以加上-U進行更新升級,如果都不行可以去 python 模塊官網 下載,然后使用 pip install *.whl 進行安裝,要看清對應的版本,否則會報錯
pip install 模塊名
pip install -U 模塊名
import tkinter
from tkinter import *
from tkinter.ttk import *
import win32api
import win32gui
import win32con
import win32ui
import time
from win32 import win32process
import psutil
import subprocess
from PIL import Image
import os
基本的GUI界面,程式的圖示可要可不要,也可以自己去制作
root = Tk()
root.title('賤工坊-視窗句柄') # 程式的標題名稱
root.geometry("480x320+512+288") # 視窗的大小及頁面的顯示位置
root.resizable(False, False) # 固定頁面不可放大縮小
root.iconbitmap("picture.ico") # 程式的圖示
在程式里創建畫布改變顏色,添加圖片,這個圖片是圓形圖示
canvas = tkinter.Canvas(root, bg="#ebebeb", height=400, width=700, borderwidth=-3) # 創建畫布
canvas.pack(side='top') # 放置畫布(為上端)
canvas_2 = tkinter.Canvas(root, bg="#ebebeb",cursor='target', height=50, width=50, borderwidth=-2) # 創建畫布
canvas_2.place(x=402, y=70) # 放置畫布(為上端)
image_file = tkinter.PhotoImage(file="./Key.png") # 加載圖片檔案
canvas_2.create_image(0, 0, anchor='nw', image=image_file) # 將圖片置于畫布上

在程式里添加文本框,用來放置資料
# 配置視窗句柄
var_hwnd = tkinter.StringVar()
tkinter.Entry(root, width=20,borderwidth=1,bg='#ebebeb',textvariable=var_hwnd).place(x=70,y=10)
# 配置標題名稱
var_title = tkinter.StringVar()
tkinter.Entry(root, width=54, borderwidth=1,bg='#ebebeb', textvariable=var_title).place(x=70, y=40)
# 配置視窗類名
var_clsname = tkinter.StringVar()
tkinter.Entry(root, width=20, borderwidth=1, bg='#ebebeb', textvariable=var_clsname).place(x=306, y=10)
# 配置執行緒ID
var_hread_id = tkinter.StringVar()
tkinter.Entry(root, width=10, borderwidth=1, bg='#ebebeb', textvariable=var_hread_id).place(x=70, y=70)
# 配置行程ID
var_process_id = tkinter.StringVar()
tkinter.Entry(root, width=10, borderwidth=1, bg='#ebebeb', textvariable=var_process_id).place(x=204, y=70)
# 配置程式名稱
var_process = tkinter.StringVar()
tkinter.Entry(root, width=29, borderwidth=1, bg='#ebebeb', textvariable=var_process).place(x=70, y=100)
# 配置程式路徑
var_p_bin = tkinter.StringVar()
tkinter.Entry(root, width=54, borderwidth=1, bg='#ebebeb', textvariable=var_p_bin).place(x=70, y=130)
# 配置CPU利用率
var_mem_percent = tkinter.StringVar()
tkinter.Entry(root, width=20, borderwidth=1, bg='#ebebeb', textvariable=var_mem_percent).place(x=70, y=160)
# 配置執行緒數
var_num_threads = tkinter.StringVar()
tkinter.Entry(root, width=20, borderwidth=1, bg='#ebebeb', textvariable=var_num_threads).place(x=306, y=160)
# 配置視窗左上
var_top = tkinter.StringVar()
tkinter.Entry(root, width=6, borderwidth=1, bg='#ebebeb', textvariable=var_top).place(x=70, y=190)
# 配置視窗左下
var_left = tkinter.StringVar()
tkinter.Entry(root, width=6, borderwidth=1, bg='#ebebeb', textvariable=var_left).place(x=70, y=220)
# 配置視窗右上
var_right = tkinter.StringVar()
tkinter.Entry(root, width=6, borderwidth=1, bg='#ebebeb', textvariable=var_right).place(x=194, y=190)
# 配置視窗右下
var_bottom = tkinter.StringVar()
tkinter.Entry(root, width=6, borderwidth=1, bg='#ebebeb', textvariable=var_bottom).place(x=194, y=220)
# 配置坐標x,y
var_point = tkinter.StringVar()
tkinter.Entry(root, width=24, borderwidth=1, bg='#ebebeb', textvariable=var_point).place(x=70, y=250)

程式添加標簽,用來標注
tkinter.Label(canvas, bg="#ebebeb", text='視窗句柄').place(x=10, y=8)
tkinter.Label(canvas, bg="#ebebeb", text='視窗標題').place(x=10, y=38)
tkinter.Label(canvas, bg="#ebebeb", text='視窗類名').place(x=248, y=8)
tkinter.Label(canvas, bg="#ebebeb", text='執行緒ID').place(x=10, y=68)
tkinter.Label(canvas, bg="#ebebeb", text='行程ID').place(x=154, y=68)
tkinter.Label(canvas, bg="#ebebeb", text='行程名稱').place(x=10, y=98)
tkinter.Label(canvas, bg="#ebebeb", text='行程路徑').place(x=10, y=128)
tkinter.Label(canvas, bg="#ebebeb", text='CPU用量').place(x=10, y=158)
tkinter.Label(canvas, bg="#ebebeb", text='執行緒數').place(x=258, y=158)
tkinter.Label(canvas, bg="#ebebeb", text='視窗左上').place(x=10, y=188)
tkinter.Label(canvas, bg="#ebebeb", text='視窗左下').place(x=10, y=218)
tkinter.Label(canvas, bg="#ebebeb", text='視窗右上').place(x=134, y=188)
tkinter.Label(canvas, bg="#ebebeb", text='視窗右下').place(x=134, y=218)
tkinter.Label(canvas, bg="#ebebeb", text='坐標x,y').place(x=10, y=248)

程式內放置一個CSDN博主二維碼,直達博主主頁,圖片的尺寸是 200x80 ,二維碼由博主制作,內置為博主的主頁鏈接
# 放置二維碼
canvas_4 = tkinter.Canvas(root, bg="red", height=80, width=200, borderwidth=-2)
canvas_4.place(x=250, y=190)
image_file_4 = tkinter.PhotoImage(file="./share.png") # 加載圖片檔案
canvas_4.create_image(0, 0, anchor='nw', image=image_file_4) # 將圖片置于畫布上

獲取滑鼠的坐標,通過坐標獲取視窗句柄,然后通過句柄獲取視窗標題、視窗類名、執行緒ID、行程ID和視窗坐標,然后通過行程ID獲取程式名稱、程式路徑、CUP用量和執行緒數,通程序式路徑獲取軟體圖示,這里關聯著滑鼠的bind <B1-Motion>左鍵持續移動,只要滑鼠左鍵持續移動則會執行如下代碼,動一下執行一次
point = win32api.GetCursorPos() # 滑鼠位置
hwnd = win32gui.WindowFromPoint(point) # 視窗句柄
title = win32gui.GetWindowText(hwnd) # 視窗標題
clsname = win32gui.GetClassName(hwnd) # 視窗類名
hread_id, process_id = win32process.GetWindowThreadProcessId(hwnd) #執行緒ID 行程ID
process = psutil.Process(process_id) # 程式名稱 通過行程ID獲取
p_bin = psutil.Process(process_id).exe() # 程式路徑 通過行程ID獲取
mem_percent = psutil.Process(process_id).memory_percent() # CPU利用率 通過行程ID獲取
num_threads = psutil.Process(process_id).num_threads() # 執行緒數 通過行程ID獲取
left, top, right, bottom = win32gui.GetWindowRect(hwnd) #視窗坐標 通過視窗句柄獲取 四個角的坐標
picture() # 更換軟體圖示
ICON(p_bin) # 獲取軟體圖示
var_hwnd.set(hwnd)
var_title.set(title)
var_clsname.set(clsname)
var_hread_id.set(hread_id)
var_process_id.set(process_id)
var_process.set(process.name())
var_p_bin.set(p_bin)
var_mem_percent.set(mem_percent)
var_num_threads.set(num_threads)
var_left.set(left)
var_top.set(top)
var_right.set(right)
var_bottom.set(bottom)
var_point.set(point)
這個代碼的用處是用來獲取軟體的圖示,通過路徑獲取,并持續保存替換 icon.png 圖片
# 獲取軟體圖示
def ICON(exePath2):
try:
exePath = exePath2.replace("\\", "/") # 替換
large, small = win32gui.ExtractIconEx(f'{exePath}', 0)
useIcon = large[0]
destroyIcon = small[0]
win32gui.DestroyIcon(destroyIcon)
hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
hbmp = win32ui.CreateBitmap()
hbmp.CreateCompatibleBitmap(hdc, ico_x, ico_x)
hdc = hdc.CreateCompatibleDC()
hdc.SelectObject(hbmp)
hdc.DrawIcon((0, 0), useIcon)
bmpstr = hbmp.GetBitmapBits(True)
img = Image.frombuffer(
'RGBA',
(32, 32),
bmpstr, 'raw', 'BGRA', 0, 1
)
img.save('icon.png')
except:
pass
將保存好扽圖片進行加載進來,pictures.png 是軟體的默認圖示,而 icon.png 則是保存下來的圖示進行替換,所以指標指向哪里就會替換為哪一個軟體的圖示,原理就是這樣,只是有一部分的軟體圖示獲取不了或使用不了,會造成軟體內圖示變白
image_file_3 = tkinter.PhotoImage(file="pictures.png") # 軟體第一次打開時要呈現的圖片
Button_2 = Button(canvas_3,image=image_file_3).place(x=0, y=0)
# 更換軟體圖示
def picture():
try:
image_file_3.config(file='icon.png') # 替換
except:
pass
這是能獲取到圖示的

這是獲取不到圖示或使用不了圖示的,只有絕少部分獲取不到或使用不了,不影響軟體的使用,

下面的是按鈕所對應的函式控制元件,用來置頂、取消置頂、顯示頂部、終止程式和打開檔案所在位置,這里要注意的是我采用的taskkill 電腦自帶的終止指令,可以不會支持win7以下的電腦命令,還有就是我這個終止命令會把程式的子程式也終止掉,所以盡量不要去嘗試終止檔案夾和桌面之類的,如果終止掉了螢屏會全白,可以使用【ctrl+alt+delete】進入任務管理器,新建任務,explorer 回車即可恢復,但是有可能你的資料都會被強行關閉,
# 置頂 通過句柄
def set_top():
try:
win32gui.SetWindowPos(var_hwnd.get(), win32con.HWND_TOPMOST, 0, 0, 0, 0,win32con.SWP_NOMOVE | win32con.SWP_NOACTIVATE | win32con.SWP_NOOWNERZORDER | win32con.SWP_SHOWWINDOW | win32con.SWP_NOSIZE)
except:
pass
# 取消置頂 通過句柄
def set_down():
try:
win32gui.SetWindowPos(var_hwnd.get(), win32con.HWND_NOTOPMOST, 0, 0, 0, 0,win32con.SWP_SHOWWINDOW | win32con.SWP_NOSIZE | win32con.SWP_NOMOVE)
except:
pass
# 顯示在頂部 通過句柄
def set_yop_p():
try:
win32gui.SetForegroundWindow(var_hwnd.get())
except:
pass
# 終止程式
def kill():
try:
subprocess.Popen("taskkill /F /T /PID " + var_process_id.get(), shell=True)
subprocess.Popen("taskkill /F /T /IM " + process.get(), shell=True)
except:
pass
# 打開檔案夾
def bin():
pbin = var_p_bin.get().replace("\\", "/") # 替換
pbin = os.path.split(pbin)[0].replace("\\", "/")
os.startfile(str(pbin))
按鈕控制元件
Button(root, text='強制置頂', command=set_top).place(x=10, y=280)
Button(root, text='取消置頂', command=set_down).place(x=100, y=280)
Button(root, text='顯示頂部', command=set_yop_p).place(x=190, y=280)
Button(root, text='強制終止', command=kill).place(x=280, y=280)
Button(root, text='打開檔案所在位置', command=bin).place(x=370, y=280)

這個是最關鍵的,只有這個控制元件才能起到指標移動是執行命令,canvas_2 指的是在 canvas_2的畫布下可以使用,<B1-Motion> 指的是滑鼠左鍵并移動 待觸發控制元件,showMenu 指的是要執行的命令函式,
# 滑鼠移動控制元件
canvas_2.bind("<B1-Motion>", showMenu)
廢話不多說,上代碼,
運行不成功的可以要注意,是不是沒有圖片,最上方有資料鏈接,里面包括圖片和源檔案,可以免費下載,代碼都不用復制了
完整代碼:
import tkinter
from tkinter import *
from tkinter.ttk import *
import win32api
import win32gui
import win32con
import win32ui
import time
from win32 import win32process
import psutil
import subprocess
from PIL import Image
import os
def main():
root = Tk()
root.title('賤工坊-視窗句柄') # 程式的標題名稱
root.geometry("480x320+512+288") # 視窗的大小及頁面的顯示位置
root.resizable(False, False) # 固定頁面不可放大縮小
root.iconbitmap("picture.ico") # 程式的圖示
canvas = tkinter.Canvas(root, bg="#ebebeb", height=400, width=700, borderwidth=-3) # 創建畫布
canvas.pack(side='top') # 放置畫布(為上端)
canvas_2 = tkinter.Canvas(root, bg="#ebebeb",cursor='target', height=50, width=50, borderwidth=-2) # 創建畫布
canvas_2.place(x=402, y=70) # 放置畫布(為上端)
image_file = tkinter.PhotoImage(file="./Key.png") # 加載圖片檔案
canvas_2.create_image(0, 0, anchor='nw', image=image_file) # 將圖片置于畫布上
canvas_3 = tkinter.Canvas(root, bg="red", height=40, width=40, borderwidth=-2) # 創建畫布
canvas_3.place(x=332, y=74) # 放置畫布(為上端)
# 配置視窗句柄
var_hwnd = tkinter.StringVar()
tkinter.Entry(root, width=20,borderwidth=1,bg='#ebebeb',textvariable=var_hwnd).place(x=70,y=10)
# 配置標題名稱
var_title = tkinter.StringVar()
tkinter.Entry(root, width=54, borderwidth=1,bg='#ebebeb', textvariable=var_title).place(x=70, y=40)
# 配置視窗類名
var_clsname = tkinter.StringVar()
tkinter.Entry(root, width=20, borderwidth=1, bg='#ebebeb', textvariable=var_clsname).place(x=306, y=10)
# 配置執行緒ID
var_hread_id = tkinter.StringVar()
tkinter.Entry(root, width=10, borderwidth=1, bg='#ebebeb', textvariable=var_hread_id).place(x=70, y=70)
# 配置行程ID
var_process_id = tkinter.StringVar()
tkinter.Entry(root, width=10, borderwidth=1, bg='#ebebeb', textvariable=var_process_id).place(x=204, y=70)
# 配置程式名稱
var_process = tkinter.StringVar()
tkinter.Entry(root, width=29, borderwidth=1, bg='#ebebeb', textvariable=var_process).place(x=70, y=100)
# 配置程式路徑
var_p_bin = tkinter.StringVar()
tkinter.Entry(root, width=54, borderwidth=1, bg='#ebebeb', textvariable=var_p_bin).place(x=70, y=130)
# 配置CPU利用率
var_mem_percent = tkinter.StringVar()
tkinter.Entry(root, width=20, borderwidth=1, bg='#ebebeb', textvariable=var_mem_percent).place(x=70, y=160)
# 配置執行緒數
var_num_threads = tkinter.StringVar()
tkinter.Entry(root, width=20, borderwidth=1, bg='#ebebeb', textvariable=var_num_threads).place(x=306, y=160)
# 配置視窗左上
var_top = tkinter.StringVar()
tkinter.Entry(root, width=6, borderwidth=1, bg='#ebebeb', textvariable=var_top).place(x=70, y=190)
# 配置視窗左下
var_left = tkinter.StringVar()
tkinter.Entry(root, width=6, borderwidth=1, bg='#ebebeb', textvariable=var_left).place(x=70, y=220)
# 配置視窗右上
var_right = tkinter.StringVar()
tkinter.Entry(root, width=6, borderwidth=1, bg='#ebebeb', textvariable=var_right).place(x=194, y=190)
# 配置視窗右下
var_bottom = tkinter.StringVar()
tkinter.Entry(root, width=6, borderwidth=1, bg='#ebebeb', textvariable=var_bottom).place(x=194, y=220)
# 配置坐標x,y
var_point = tkinter.StringVar()
tkinter.Entry(root, width=24, borderwidth=1, bg='#ebebeb', textvariable=var_point).place(x=70, y=250)
image_file_3 = tkinter.PhotoImage(file="pictures.png") # 軟體第一次打開時要呈現的圖片
Button_2 = Button(canvas_3, image=image_file_3).place(x=0, y=0)
# 更換軟體圖示
def picture():
try:
image_file_3.config(file='icon.png') # 替換
except:
pass
# 圖示尺寸
ico_x = 32
# 獲取軟體圖示
def ICON(exePath2):
try:
exePath = exePath2.replace("\\", "/") # 替換
large, small = win32gui.ExtractIconEx(f'{exePath}', 0)
useIcon = large[0]
destroyIcon = small[0]
win32gui.DestroyIcon(destroyIcon)
hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
hbmp = win32ui.CreateBitmap()
hbmp.CreateCompatibleBitmap(hdc, ico_x, ico_x)
hdc = hdc.CreateCompatibleDC()
hdc.SelectObject(hbmp)
hdc.DrawIcon((0, 0), useIcon)
bmpstr = hbmp.GetBitmapBits(True)
img = Image.frombuffer(
'RGBA',
(32, 32),
bmpstr, 'raw', 'BGRA', 0, 1
)
img.save('icon.png')
except:
pass
# 通過滑鼠移動獲取函式
def showMenu(event):
try:
point = win32api.GetCursorPos() # 滑鼠位置
hwnd = win32gui.WindowFromPoint(point) # 視窗句柄
title = win32gui.GetWindowText(hwnd) # 視窗標題
clsname = win32gui.GetClassName(hwnd) # 視窗類名
hread_id, process_id = win32process.GetWindowThreadProcessId(hwnd) #執行緒ID 行程ID
process = psutil.Process(process_id) # 程式名稱 通過行程ID獲取
p_bin = psutil.Process(process_id).exe() # 程式路徑 通過行程ID獲取
mem_percent = psutil.Process(process_id).memory_percent() # CPU利用率 通過行程ID獲取
num_threads = psutil.Process(process_id).num_threads() # 執行緒數 通過行程ID獲取
left, top, right, bottom = win32gui.GetWindowRect(hwnd) #視窗坐標 通過視窗句柄獲取 四個角的坐標
picture() # 更換軟體圖示
ICON(p_bin) # 獲取軟體圖示
var_hwnd.set(hwnd)
var_title.set(title)
var_clsname.set(clsname)
var_hread_id.set(hread_id)
var_process_id.set(process_id)
var_process.set(process.name())
var_p_bin.set(p_bin)
var_mem_percent.set(mem_percent)
var_num_threads.set(num_threads)
var_left.set(left)
var_top.set(top)
var_right.set(right)
var_bottom.set(bottom)
var_point.set(point)
except:
pass
# 置頂 通過句柄
def set_top():
try:
win32gui.SetWindowPos(var_hwnd.get(), win32con.HWND_TOPMOST, 0, 0, 0, 0,win32con.SWP_NOMOVE | win32con.SWP_NOACTIVATE | win32con.SWP_NOOWNERZORDER | win32con.SWP_SHOWWINDOW | win32con.SWP_NOSIZE)
except:
pass
# 取消置頂 通過句柄
def set_down():
try:
win32gui.SetWindowPos(var_hwnd.get(), win32con.HWND_NOTOPMOST, 0, 0, 0, 0,win32con.SWP_SHOWWINDOW | win32con.SWP_NOSIZE | win32con.SWP_NOMOVE)
except:
pass
# 顯示在頂部 通過句柄
def set_yop_p():
try:
win32gui.SetForegroundWindow(var_hwnd.get())
except:
pass
# 終止程式
def kill():
try:
subprocess.Popen("taskkill /F /T /PID " + var_process_id.get(), shell=True)
subprocess.Popen("taskkill /F /T /IM " + process.get(), shell=True)
except:
pass
# 打開檔案夾
def bin():
pbin = var_p_bin.get().replace("\\", "/") # 替換
pbin = os.path.split(pbin)[0].replace("\\", "/")
os.startfile(str(pbin))
def Label():
# 標簽
tkinter.Label(canvas, bg="#ebebeb", text='視窗句柄').place(x=10, y=8)
tkinter.Label(canvas, bg="#ebebeb", text='視窗標題').place(x=10, y=38)
tkinter.Label(canvas, bg="#ebebeb", text='視窗類名').place(x=248, y=8)
tkinter.Label(canvas, bg="#ebebeb", text='執行緒ID').place(x=10, y=68)
tkinter.Label(canvas, bg="#ebebeb", text='行程ID').place(x=154, y=68)
tkinter.Label(canvas, bg="#ebebeb", text='行程名稱').place(x=10, y=98)
tkinter.Label(canvas, bg="#ebebeb", text='行程路徑').place(x=10, y=128)
tkinter.Label(canvas, bg="#ebebeb", text='CPU用量').place(x=10, y=158)
tkinter.Label(canvas, bg="#ebebeb", text='執行緒數').place(x=258, y=158)
tkinter.Label(canvas, bg="#ebebeb", text='視窗左上').place(x=10, y=188)
tkinter.Label(canvas, bg="#ebebeb", text='視窗左下').place(x=10, y=218)
tkinter.Label(canvas, bg="#ebebeb", text='視窗右上').place(x=134, y=188)
tkinter.Label(canvas, bg="#ebebeb", text='視窗右下').place(x=134, y=218)
tkinter.Label(canvas, bg="#ebebeb", text='坐標x,y').place(x=10, y=248)
# 滑鼠移動控制元件
canvas_2.bind("<B1-Motion>", showMenu)
Button(root, text='強制置頂', command=set_top).place(x=10, y=280)
Button(root, text='取消置頂', command=set_down).place(x=100, y=280)
Button(root, text='顯示頂部', command=set_yop_p).place(x=190, y=280)
Button(root, text='強制終止', command=kill).place(x=280, y=280)
Button(root, text='打開檔案所在位置', command=bin).place(x=370, y=280)
# 放置二維碼
canvas_4 = tkinter.Canvas(root, bg="red", height=80, width=200, borderwidth=-2)
canvas_4.place(x=250, y=190)
image_file_4 = tkinter.PhotoImage(file="./share.png") # 加載圖片檔案
canvas_4.create_image(0, 0, anchor='nw', image=image_file_4) # 將圖片置于畫布上
Label()
root.mainloop() #運行
if __name__ == '__main__':
main()

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/413446.html
標籤:python
上一篇:Pytest系列:csdn最最最詳細,聽不懂你找我。 skip、skipif跳過用例
下一篇:利用Joypy繪制嵴線圖的案例
