gpt4 book ai didi

python - 强制键盘焦点到 LineEdit QT

转载 作者:行者123 更新时间:2023-12-04 07:15:56 33 4
gpt4 key购买 nike

我正在尝试为 Windows 开发一个由全局键绑定(bind)触发的覆盖弹出窗口,一旦按下键绑定(bind),它应该将焦点捕获到 QLineEdit 中。问题是,如果它被聚焦一次,但我点击外部有效地移除焦点,那么之后就无法重新获得焦点。
这是我试图用来强制键盘焦点在 QLineEdit 上的代码的简化版本:

from PySide6 import QtCore, QtWidgets, QtGui
from pynput import keyboard

class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()

self.input = QtWidgets.QLineEdit()
self.layout = QtWidgets.QVBoxLayout(self)
self.layout.addWidget(self.input)

self.input.setWindowModality(QtCore.Qt.ApplicationModal)
self.setWindowState(QtCore.Qt.WindowActive)
self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)

@QtCore.Slot()
def toggle_visible(self):
if self.isVisible():
print("Hiding popup")
self.hide()
else:
print("Showing popup")
self.show()
self.activateWindow()
self.input.grabKeyboard()
self.input.setFocus()

class KeybindPressed(QtCore.QObject):
keybind_pressed = QtCore.Signal()

def __call__(self):
self.keybind_pressed.emit()


if __name__ == "__main__":
app = QtWidgets.QApplication([])

pressed = KeybindPressed()
with keyboard.GlobalHotKeys({"<alt>+<space>": pressed}):

widget = MyWidget()
pressed.keybind_pressed.connect(widget.toggle_visible)
widget.resize(800, 600)
widget.show()

app.exec()
这是一段记录,显示焦点停留在其他应用程序中而不是在显示时返回窗口的不良行为。
enter image description here

最佳答案

感谢 ekhumoro我能够弄清楚如何强制专注于 window 。以下是强制焦点所需的代码:
导入和设置

windows = False
if os.name == "nt":
import win32gui, win32con, win32process, win32api
win32gui.SystemParametersInfo(win32con.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, win32con.SPIF_SENDWININICHANGE | win32con.SPIF_UPDATEINIFILE)
windows = True
实际强制焦点的代码,当您的窗口应该获得焦点时会调用它:
def force_focus(qt_widget_instance: QtWidgets.QWidget):
if windows:
fgwin = win32gui.GetForegroundWindow()
fg = win32process.GetWindowThreadProcessId(fgwin)[0]
current = win32api.GetCurrentThreadId()
if current != fg:
win32process.AttachThreadInput(fg, current, True)
win32gui.SetForegroundWindow(qt_widget_instance.winId())
win32process.AttachThreadInput(fg, win32api.GetCurrentThreadId(), False)
这是实现此功能的完整示例:
from PySide6 import QtCore, QtWidgets, QtGui
from pynput import keyboard

import os

windows = False
if os.name == "nt":
import win32gui, win32con, win32process, win32api
win32gui.SystemParametersInfo(win32con.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, win32con.SPIF_SENDWININICHANGE | win32con.SPIF_UPDATEINIFILE)
windows = True

def force_focus(qt_widget_instance: QtWidgets.QWidget):
if windows:
fgwin = win32gui.GetForegroundWindow()
fg = win32process.GetWindowThreadProcessId(fgwin)[0]
current = win32api.GetCurrentThreadId()
if current != fg:
win32process.AttachThreadInput(fg, current, True)
win32gui.SetForegroundWindow(qt_widget_instance.winId())
win32process.AttachThreadInput(fg, win32api.GetCurrentThreadId(), False)

class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()

self.input = QtWidgets.QLineEdit()
self.layout = QtWidgets.QVBoxLayout(self)
self.layout.addWidget(self.input)

self.input.setWindowModality(QtCore.Qt.ApplicationModal)
self.setWindowState(QtCore.Qt.WindowActive)
self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)

@QtCore.Slot()
def toggle_visible(self):
if self.isVisible():
print("Hiding popup")
self.hide()
else:
print("Showing popup")
self.show()
force_focus(self)
self.activateWindow()
self.input.grabKeyboard()
self.input.setFocus()



class KeybindPressed(QtCore.QObject):
keybind_pressed = QtCore.Signal()

def __call__(self):
self.keybind_pressed.emit()


if __name__ == "__main__":
app = QtWidgets.QApplication([])

pressed = KeybindPressed()
with keyboard.GlobalHotKeys({"<cmd>+<space>": pressed}):

widget = MyWidget()
pressed.keybind_pressed.connect(widget.toggle_visible)
widget.resize(800, 600)
widget.show()

app.exec()

关于python - 强制键盘焦点到 LineEdit QT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68764703/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com