windows Python窗口激活

u91tlkcl  于 2022-11-18  发布在  Windows
关注(0)|答案(7)|浏览(360)

我如何在Windows中用Python编程激活一个窗口呢?我正在向它发送击键,现在我只是想确定它是最后一个使用的应用程序,然后发送击键Alt+Tab从DOS控制台切换到它。有没有更好的方法(因为我的经验告诉我,这种方法绝不是万无一失的)?

gzjq41n4

gzjq41n41#

你可以使用win32gui模块来完成这个任务。首先你需要在你的窗口上获得一个有效的句柄。如果你知道窗口的类名或者确切的标题,你可以使用win32gui.FindWindow。如果不知道,你可以用win32gui.EnumWindows枚举窗口,然后尝试找到正确的窗口。
一旦你有了句柄,你就可以用这个句柄调用win32gui.SetForegroundWindow,它将激活窗口,并准备好接受你的击键。
请看下面的一个例子。我希望它能有所帮助

import win32gui
import re

class WindowMgr:
    """Encapsulates some calls to the winapi for window management"""

    def __init__ (self):
        """Constructor"""
        self._handle = None

    def find_window(self, class_name, window_name=None):
        """find a window by its class_name"""
        self._handle = win32gui.FindWindow(class_name, window_name)

    def _window_enum_callback(self, hwnd, wildcard):
        """Pass to win32gui.EnumWindows() to check all the opened windows"""
        if re.match(wildcard, str(win32gui.GetWindowText(hwnd))) is not None:
            self._handle = hwnd

    def find_window_wildcard(self, wildcard):
        """find a window whose title matches the wildcard regex"""
        self._handle = None
        win32gui.EnumWindows(self._window_enum_callback, wildcard)

    def set_foreground(self):
        """put the window in the foreground"""
        win32gui.SetForegroundWindow(self._handle)

w = WindowMgr()
w.find_window_wildcard(".*Hello.*")
w.set_foreground()
zbwhf8kr

zbwhf8kr2#

PywinautoSWAPY可能需要最少的工作to set the focus of a window
使用SWAPY自动生成检索窗口对象所需的python代码,例如:

import pywinauto

# SWAPY will record the title and class of the window you want activated
app = pywinauto.application.Application()
t, c = u'WINDOW SWAPY RECORDS', u'CLASS SWAPY RECORDS'
handle = pywinauto.findwindows.find_windows(title=t, class_name=c)[0]
# SWAPY will also get the window
window = app.window_(handle=handle)

# this here is the only line of code you actually write (SWAPY recorded the rest)
window.SetFocus()

如果其他窗口碰巧在感兴趣的窗口前面,这不是一个问题。This additional code或这将确保它在运行上面的代码之前显示:

# minimize then maximize to bring this window in front of all others
window.Minimize()
window.Maximize()
# now you can set its focus
window.SetFocus()
brvekthn

brvekthn3#

import ctypes, platform

if platform.system() == 'Windows':
    Active_W = ctypes.windll.user32.GetActiveWindow()
    ctypes.windll.user32.SetWindowPos(Active_W,0,0,0,0,0,0x0002|0x0001)

我们开始吧。你只需要存储活动窗口的值。

5sxhfpxr

5sxhfpxr4#

Pip安装键盘。在你设置前台窗口之前,模拟一个键盘到esc,这是键盘。send('esc ')你可能想做三次以下任一:
1.侧边栏

  1. Windows键覆盖
    1.始终位于顶层的任务管理器
mv1qrgav

mv1qrgav5#

使用SetWindowPosSetForegroundWindow可能不够,如果窗口是minifiedaka IsIconic!我们可以使用ShowWindowSW_RESTORE(9):

import ctypes

def activate_window(hwnd):
    user32 = ctypes.windll.user32
    user32.SetForegroundWindow(hwnd)
    if user32.IsIconic(hwnd):
        user32.ShowWindow(hwnd, 9)

根据您如何识别所需的窗口,有一些方法可以获得hwnd(又名窗口句柄)。
你可以通过user32.GetWindowThreadProcessId根据pid或者通过user32.GetWindowTextW根据窗口名loop through all the windows来找到正确的句柄
要获取ProcessIds,您可以使用Windows内置的wmic。您可以使用它执行许多其他漂亮的操作。(所有属性:wmic process get /?)(get handle是断开的tho)例如:

def get_pids(proc_name):
    out = subprocess.check_output('wmic process where Name="%s" get ProcessId' % proc_name)
    pids = out.decode().strip().split()[1:]
    if not pids:
        raise WindowsError('Could not find pids for process')
    return [int(pid) for pid in pids]
s71maibg

s71maibg6#

保持窗口活动的GUI应用程序

Python3

  • 安装库 *
pip install pywin32
  • 将以下代码另存为**alive.pyw**文件 *
from ctypes import windll, wintypes, byref, c_uint, sizeof, Structure
import tkinter as tk
import ctypes
import sys
import threading
import time
import win32api
import win32con

stop_threads = True
SET_IDLE_TIME = 40 #in seconds
tm1 = time.time()
value = 0

class LASTINPUTINFO(Structure):
    _fields_ = [
        ('cbSize', c_uint),
        ('dwTime', c_uint),
    ]

def get_idle_duration():
    global value, tm1
    lastInputInfo = LASTINPUTINFO()
    lastInputInfo.cbSize = sizeof(lastInputInfo)
    windll.user32.GetLastInputInfo(byref(lastInputInfo))

    # millis = 4294967 - lastInputInfo.dwTime - windll.kernel32.GetTickCount()
    # print(windll.kernel32.GetTickCount(), lastInputInfo.dwTime, sizeof(lastInputInfo), millis)
    tm2 = time.time() - tm1
    last_idel_time = lastInputInfo.dwTime
    # print()
    if value != last_idel_time:
        value = last_idel_time
        tm2 = time.time() - time.time()
        tm1 = time.time()
    # print("time:", tm1)
    return tm2

def press_key_2():
    global stop_threads, tm1
    while True:
        if not stop_threads:
            break
        idle_time = get_idle_duration() #seconds
        # print(idle_time)
        g = float("{:.2f}".format(idle_time))
        st = str(g) + " / " + str(SET_IDLE_TIME)
        var.set(st)
        time.sleep(0.1)
        if idle_time < SET_IDLE_TIME:
            continue

        print("in ideal state pressing cltr")
        win32api.keybd_event(ord('x'), 0, win32con.KEYEVENTF_EXTENDEDKEY, 0)
        tm1 = time.time()

#---------------- Monitor threads ------------------------------

t1 = threading.Thread(target=press_key_2, name='t1')
t1.daemon = True

#----------------- TK functions ----------------------

def display_on():
    global tk, t1, stop_threads
    stop_threads = True
    print("Always On")
    ctypes.windll.kernel32.SetThreadExecutionState(0x80000002)
    root.iconify()
    t1.start()
    # t2.start()

def display_reset():
    print("quit pressed")
    global stop_threads
    stop_threads = False
    ctypes.windll.kernel32.SetThreadExecutionState(0x80000000)
    sys.exit(0)


root = tk.Tk()
root.geometry("200x110")
root.title("Devil")
frame = tk.Frame(root)
frame.pack()

var = tk.StringVar()
var_idle = tk.StringVar()

label = tk.Label(frame, textvariable =  var)#, bd = 5, justify = tk.RIGHT, padx = 10, pady = 10)
label_idle = tk.Label(frame,textvariable = var_idle)
var_idle.set("Idle Time")
var.set("-")
button = tk.Button(frame,
                   text="Quit",
                   fg="red",
                   command=display_reset)

slogan = tk.Button(frame,
                   text="Always ON",
                   command=display_on)

label_idle.pack(side=tk.BOTTOM,padx=15, pady=13)
label.pack(side=tk.BOTTOM,padx=15, pady=5)

slogan.pack(side=tk.LEFT,padx=15, pady=5)
button.pack(side=tk.LEFT,padx=15, pady=5)

root.mainloop()
ctypes.windll.kernel32.SetThreadExecutionState(0x80000000)
yjghlzjz

yjghlzjz7#

为了补充@luc的答案,下面是当存在多个窗口时,代码如何更详细地说明它所选择的句柄:
pip install pywin32之后,运行

import win32gui
import re

class WindowMgr:
  """Encapsulates some calls to the winapi for window management"""

  def __init__ (self):
    """Constructor"""
    self._handle = None
    self._handles = []

  def find_window(self, class_name, window_name=None):
    """find a window by its class_name"""
    self._handle = win32gui.FindWindow(class_name, window_name)

  def _window_enum_callback(self, hwnd, wildcard):
    """Pass to win32gui.EnumWindows() to check all the opened windows"""
    if re.match(wildcard, str(win32gui.GetWindowText(hwnd))) is not None:
      self._handles.append(hwnd)
      self._handle = hwnd

  def find_window_wildcard(self, wildcard):
    """find a window whose title matches the wildcard regex"""
    self._handle = None
    self._handles = []
    win32gui.EnumWindows(self._window_enum_callback, wildcard)

    self.set_handle()

  def set_foreground(self):
    """put the window in the foreground"""
    if self._handle != None:
      win32gui.SetForegroundWindow(self._handle)
    else:
      print("No handle is selected, couldn't set focus")

  def set_handle(self):
    """get one handle to operate on from all the matched handles"""
    if len(self._handles) < 1:
      print("Matched no window")
      return False

    if len(self._handles) > 1:
      print("Selecting the first handle of multiple windows:")
    else: # len(self._handles) == 1:
      print("Matched a single window:")

    self.print_matches()
    self._handle = self._handles[0]
    return True

  def print_matches(self):
    """print the title of each matched handle"""
    for hwnd in self._handles:
      print("- " + str(win32gui.GetWindowText(hwnd)))

w = WindowMgr()
w.find_window_wildcard(".*Hello.*")
w.set_foreground()
  • 注意:我无法通过编辑@luc的答案进行添加,因为它的建议编辑队列已满。*

相关问题