Python 如何将QT窗口从其他进程还原到系统托盘中?

Python 如何将QT窗口从其他进程还原到系统托盘中?,python,qt,winapi,pyside,Python,Qt,Winapi,Pyside,这是大系统中的一个特性。我们将问题简化为下面的示例代码 在示例中,我们可以单击“隐藏”以最小化系统托盘中的窗口,同时隐藏任务栏按钮。如果我们单击托盘按钮,隐藏的窗口可以再次显示 我们希望实现这个特性:当一个实例已经启动并且窗口已经最小化到系统托盘中时,我们启动另一个实例(使用相同的脚本),然后新实例激活旧实例的窗口并将其显示出来 新实例使用FindWindow API获取窗口句柄,问题是找不到旧实例窗口的句柄。因此,我们无法找到窗口句柄以再次显示它。 有人能帮助找到实现该功能的解决方案吗 fro

这是大系统中的一个特性。我们将问题简化为下面的示例代码

在示例中,我们可以单击“隐藏”以最小化系统托盘中的窗口,同时隐藏任务栏按钮。如果我们单击托盘按钮,隐藏的窗口可以再次显示

我们希望实现这个特性:当一个实例已经启动并且窗口已经最小化到系统托盘中时,我们启动另一个实例(使用相同的脚本),然后新实例激活旧实例的窗口并将其显示出来

新实例使用FindWindow API获取窗口句柄,问题是找不到旧实例窗口的句柄。因此,我们无法找到窗口句柄以再次显示它。 有人能帮助找到实现该功能的解决方案吗

from PySide import QtGui, QtCore
from PySide.QtCore import *
from PySide.QtGui import *
import sys
import os
import tempfile
import win32gui

# enable Ctrl-C to breakdown
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)

# checkSingleton : code modifieed from tendo.SingletInstance
def checkSingleton():

    basename = os.path.splitext(os.path.abspath(sys.argv[0]))[0].replace(
        "/", "-").replace(":", "").replace("\\", "-")  + '.lock'
    lockfile = os.path.normpath(tempfile.gettempdir() + '/' + basename)

    success = False
    try:
        if os.path.exists(lockfile):
            os.unlink(lockfile)
        fd = os.open(lockfile, os.O_CREAT | os.O_EXCL | os.O_RDWR)
        success = True
    except OSError:
        pass

    return success

class MyWin(QWidget):
    def __init__(self):  
        super(MyWin, self).__init__()
        self.setWindowTitle("MyWin")
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint)
        self.tray = QtGui.QSystemTrayIcon(QtGui.QIcon("logo.png"), self)
        self.tray.activated.connect(self.trayClicked)
        self.tray.show()

        btn = QPushButton("Hide")
        btn.clicked.connect(self.onHide)
        btn2 = QPushButton("Close")
        btn2.clicked.connect(self.onClose)

        out = QVBoxLayout()
        out.addWidget(btn)
        out.addWidget(btn2)
        self.setLayout(out)

    def onHide(self):
        self.setWindowFlags(self.windowFlags() | Qt.Tool)
        self.showMinimized()

    def onClose(self):
        sys.exit()

    def showUp(self):
        self.setWindowFlags(self.windowFlags() & (~Qt.Tool))

        self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowStaysOnTopHint)
        self.setWindowState(Qt.WindowActive)        
        self.show()

    def trayClicked(self, reason):
        if reason == QtGui.QSystemTrayIcon.Trigger:
            self.showUp()

app = QtGui.QApplication(sys.argv)

ret = checkSingleton()
if ret:
    win= MyWin()
    win.setGeometry(100,100,300,300)
    win.show()
    app.exec_()
else:
    print "One instance has already been running"
    hwnd = win32gui.FindWindow("QWidget","MyWin")  # < ==  Fail to find the handle of window instance
    if hwnd != 0:
        win32gui.SetForegroundWindow(hwnd)
        win32gui.ShowWindow(hwnd, 1)
从PySide导入QtGui,QtCore
从PySide.QtCore导入*
从PySide.QtGui导入*
导入系统
导入操作系统
导入临时文件
导入win32gui
#启用Ctrl-C进行分解
输入信号
signal.signal(signal.SIGINT,signal.SIG_-DFL)
#checkSingleton:从tendo.SingletInstance修改的代码
def checkSingleton():
basename=os.path.splitext(os.path.abspath(sys.argv[0]))[0]。替换(
“/”、“-”。替换(“:”、“”)。替换(“\\”、“-”+”。锁定”
lockfile=os.path.normpath(tempfile.gettempdir()+'/'+basename)
成功=错误
尝试:
如果os.path.exists(锁文件):
取消链接(锁文件)
fd=os.open(锁文件,os.O_创建| os.O_排除| os.O_RDWR)
成功=正确
除操作错误外:
通过
回归成功
MyWin类(QWidget):
定义初始化(自):
超级(MyWin,self)。\uuuu init\uuuuu()
self.setWindowTitle(“MyWin”)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint)
self.tray=QtGui.QSystemTrayIcon(QtGui.QIcon(“logo.png”),self)
自.托盘.已激活.连接(自.托盘已锁定)
self.tray.show()
btn=QPushButton(“隐藏”)
btn.clicked.connect(self.onHide)
btn2=QPushButton(“关闭”)
btn2.clicked.connect(self.onClose)
out=QVBoxLayout()
out.addWidget(btn)
out.addWidget(btn2)
self.setLayout(输出)
def onHide(自我):
self.setWindowFlags(self.windowFlags()| Qt.Tool)
self.showMinimized()
def onClose(自我):
sys.exit()
def展示(自我):
self.setWindowFlags(self.windowFlags()&(~Qt.Tool))
self.setWindowFlags(self.windowFlags()| Qt.WindowStaysOnTopHint)
self.setWindowFlags(self.windowFlags()&~Qt.WindowStaysOnTopHint)
self.setWindowsState(Qt.WindowActive)
self.show()
def trayClicked(自身、原因):
如果原因==QtGui.QSystemTrayIcon.Trigger:
self.showUp()
app=QtGui.QApplication(sys.argv)
ret=checkSingleton()
如果ret:
win=MyWin()
win.setGeometry(100300300)
win.show()
app.exec()
其他:
打印“一个实例已在运行”
hwnd=win32gui.FindWindow(“QWidget”、“MyWin”)#<==找不到窗口实例的句柄
如果hwnd!=0:
win32gui.SetForegroundWindow(hwnd)
win32gui.ShowWindow(hwnd,1)

我们使用Spy++搜索窗口,内存中没有“MyWin”命名的窗口。

不清楚您在问什么。您是否正在尝试实现一个单实例应用程序,其中任何启动后续实例的尝试都将还原现有实例并将其置于Z顺序的顶部?请尝试:
win32gui.FindWindow(None,“MyWin”)
@IInspectable,是的,您的描述是正确的。当现有实例位于某个窗口后面时,我们的脚本可以工作,但当现有实例最小化到系统托盘中时,脚本会失败。@ekhumoro,win32gui.FindWindow(None,“MyWin”)也找不到句柄。我使用spy++检测到,当现有实例最小化为系统托盘时,没有“MyWin”命名窗口。@Azure。那么spy++是否检测到了窗口?如果没有,很难看到如何使用
FindWindow
。。。