考虑以下这段代码:
import subprocess
import win32gui
import win32con
import time
import sys
from PyQt5.Qt import * # noqa
class Mcve(QMainWindow):
def __init__(self, path_exe):
super().__init__()
menu = self.menuBar()
attach_action = QAction('Attach', self)
attach_action.triggered.connect(self.attach)
menu.addAction(attach_action)
detach_action = QAction('Detach', self)
detach_action.triggered.connect(self.detach)
menu.addAction(detach_action)
self.dock = QDockWidget("Attach window", self)
self.addDockWidget(Qt.RightDockWidgetArea, self.dock)
p = subprocess.Popen(path_exe)
time.sleep(0.5) # Give enough time so FindWindowEx won't return 0
self.hwnd = win32gui.FindWindowEx(0, 0, "CalcFrame", None)
if self.hwnd == 0:
raise Exception("Process not found")
def detach(self):
try:
self._window.setParent(None)
# win32gui.SetWindowLong(self.hwnd, win32con.GWL_EXSTYLE, self._style)
self._window.show()
self.dock.setWidget(None)
self._widget = None
self._window = None
except Exception as e:
import traceback
traceback.print_exc()
def attach(self):
# self._style = win32gui.GetWindowLong(self.hwnd, win32con.GWL_EXSTYLE)
self._window = QWindow.fromWinId(self.hwnd)
self._widget = self.createWindowContainer(self._window)
self.dock.setWidget(self._widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Mcve("C:\\Windows\\system32\\calc.exe")
w.show()
sys.exit(app.exec_())
这里的目标是修复代码,以便将窗口正确附加/分离到QDockWidget中。现在,代码有两个重要问题。
原始窗口的样式被弄乱了:
a)在连接之前(计算器具有菜单栏)
b)连接后(计算器菜单栏消失了)
c)分离时(菜单栏未正确还原)
我已经尝试过使用flags / setFlags qt函数或getWindowLong / setWindowLong位,但我的尝试还不够运气
如果您已经将计算器连接到主窗口并从其上拆下,然后决定关闭主窗口,则您肯定希望所有东西(pyqt进程)都被正确地关闭和清理,现在不是这种情况了,为什么?< / p>
实际上,在将计算器连接/分离到主窗口后,Python进程将挂起,并且您需要手动强制终止进程(即:ctrl + break锥体,ctrl + c cmd提示符) ...表示在父母/父母抚养父母时,代码工作不正确
其他说明:
explorer.exe
生成的现有非子进程。答案 0 :(得分:0)
我发现部分问题要解决。因此,当您在self._window
函数中创建attach
并关闭MainWindow
时,另一个窗口(线程)仍然静止不动。因此,如果您在self._window = None
函数中添加__init__
并按如下所示添加__del__
函数,则该部分是固定的。仍然不确定缺少菜单。我还建议您使用self.__p
握住子进程句柄,而不要放任其走。还应将其包括在__del__
中。
def __del__(self):
self.__p.terminate()
if self._window:
print('terminating window')
self._window.close
可能更好的方法是包括一个closeEvent
def closeEvent(self, event):
print('Closing time')
self.__p.terminate()
if self._window is not None:
print('terminating window')
self._window.close