首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >嵌入式应用中的PyQT5焦点问题

嵌入式应用中的PyQT5焦点问题
EN

Stack Overflow用户
提问于 2022-10-05 19:52:41
回答 1查看 103关注 0票数 0

我的安装程序是python3.9和Windows10上的PyQT5

我一直在使用QtGui.QWindow.fromWinId(<window_handle>)函数成功地将VNCviewer、WinSCP等软件嵌入到python中。当我嵌入控制台应用程序(PuTTY SSH会话、命令提示符)时,它不接受键盘或鼠标输入。python窗口有焦点,但它显示嵌入的窗口不响应键盘或鼠标。

代码:

代码语言:javascript
复制
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应用程序需要失去焦点,对于如何做到这一点有什么想法吗?

我尝试过这个解决方案,但它对我不起作用(滚动到最后的评论)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-07 17:43:42

前言:使用焦点事件处理程序,而不是鼠标移动处理程序来执行此

您可以使用win32gui强制嵌入式窗口处于活动状态,即使它已被qt吸收。

代码语言:javascript
复制
win32gui.BringWindowToTop(hWnd)
win32gui.SetFocus(hWnd)

在这个例子中,我包含了它,每次它检测到GUI中的鼠标移动时都会运行。理想情况下,您希望每次单击QWidget内部时都要执行它,但我对PyQT5相对来说并不熟悉,而且还没有学会如何正确地执行。

示例中的固定代码:

代码语言:javascript
复制
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()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73965650

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档