我的安装程序是python3.9和Windows10上的PyQT5
我一直在使用QtGui.QWindow.fromWinId(<window_handle>)
函数成功地将VNCviewer、WinSCP等软件嵌入到python中。当我嵌入控制台应用程序(PuTTY SSH会话、命令提示符)时,它不接受键盘或鼠标输入。python窗口有焦点,但它显示嵌入的窗口不响应键盘或鼠标。
代码:
class MainWindow(QMainWindow):
"""
Launches the terminal
"""
def __init__(self, command: str, substring: str):
super(MainWindow, self).__init__()
widget = QWidget()
layout = QGridLayout(widget)
self.setCentralWidget(widget)
win = latchToWindow(command, substring)
hwnd = win._hWnd
self.window = QtGui.QWindow.fromWinId(hwnd)
self.windowcontainer = self.createWindowContainer(self.window, widget)
layout.addWidget(self.windowcontainer, 0, 0)
def latchToWindow(winLaunchCommand: str, gettitle: str):
"""
Used when there are additional dialogs and you need to grab a specific one
:param winLaunchCommand:
:param title:
:return:
"""
makeNewWindow(winLaunchCommand)
while True:
windows = pygetwindow.getAllWindows()
for win in windows:
tempTitle = win.title
if gettitle in tempTitle:
return win
time.sleep(0.1)
def makeNewWindow(winLaunchCommand: str):
"""
Makes a new window with that command, and returns that window
:param winLaunchCommand:
:return:
"""
windows = pygetwindow.getAllWindows()
os.popen(winLaunchCommand)
while True:
newWindow = pygetwindow.getAllWindows()
if len(newWindow) != len(windows):
for win in newWindow:
if win.title != "":
if win not in windows:
time.sleep(0.05)
return win
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle("fusion")
# This doesn't work with keyboard and mouse
form = MainWindow("start cmd.exe", "cmd.exe")
# This does work with keyboard and mouse
// form = MainWindow("putty.exe", "PuTTY")
form.setWindowTitle('Embedded Python Terminal')
form.show()
app.exec()
截图:
编辑我了解到问题是pyqt5在焦点,命令提示符不在焦点。需要发生的是,当单击嵌入式窗口时,窗口是集中的,而pyqt应用程序需要失去焦点,对于如何做到这一点有什么想法吗?
我尝试过这个解决方案,但它对我不起作用(滚动到最后的评论)
发布于 2022-10-07 17:43:42
前言:使用焦点事件处理程序,而不是鼠标移动处理程序来执行此。
您可以使用win32gui
强制嵌入式窗口处于活动状态,即使它已被qt吸收。
win32gui.BringWindowToTop(hWnd)
win32gui.SetFocus(hWnd)
在这个例子中,我包含了它,每次它检测到GUI中的鼠标移动时都会运行。理想情况下,您希望每次单击QWidget内部时都要执行它,但我对PyQT5相对来说并不熟悉,而且还没有学会如何正确地执行。
示例中的固定代码:
class MainWindow(QMainWindow):
"""
Launches the terminal
"""
def __init__(self, command: str, substring: str):
super(MainWindow, self).__init__()
win = latchToWindow(command, substring)
self.hwnd = win._hWnd
widget = widgetMouseTracking(self.hwnd)
widget.setMouseTracking(True)
layout = QGridLayout(widget)
self.setCentralWidget(widget)
self.window = QtGui.QWindow.fromWinId(self.hwnd)
self.windowcontainer = self.createWindowContainer(self.window, widget)
layout.addWidget(self.windowcontainer, 0, 0)
class widgetMouseTracking(QWidget):
def __init__(self, windowsID):
super().__init__()
self.id = windowsID
def mouseMoveEvent(self, a0: QtGui.QMouseEvent):
win32gui.BringWindowToTop(self.id)
win32gui.SetFocus(self.id)
def latchToWindow(winLaunchCommand: str, gettitle: str):
"""
Used when there are additional dialogs and you need to grab a specific one
:param winLaunchCommand:
:param title:
:return:
"""
makeNewWindow(winLaunchCommand)
while True:
windows = pygetwindow.getAllWindows()
for win in windows:
tempTitle = win.title
if gettitle in tempTitle:
return win
time.sleep(0.1)
def makeNewWindow(winLaunchCommand: str):
"""
Makes a new window with that command, and returns that window
:param winLaunchCommand:
:return:
"""
windows = pygetwindow.getAllWindows()
os.popen(winLaunchCommand)
while True:
newWindow = pygetwindow.getAllWindows()
if len(newWindow) != len(windows):
for win in newWindow:
if win.title != "":
if win not in windows:
time.sleep(0.05)
return win
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle("fusion")
# This doesn't work with keyboard and mouse
form = MainWindow("start cmd.exe", "cmd.exe")
# This does work with keyboard and mouse
# form = MainWindow("putty.exe", "PuTTY")
form.setWindowTitle('Embedded Python Terminal')
form.show()
app.exec()
https://stackoverflow.com/questions/73965650
复制相似问题