By "embedding" here, I mean that we take a non-Qt program window and embed it into a certain kind of Qt widget. Then we can put that widget where ever we want in our Qt program. Side by side, whatever. With a Qt widget A, we can attach it to another one, B, like a splitter, by making B be the "parent" of A. If A has no parent, it will be a free-floating window. With a non-Qt window like that calculator, we get its window ID from Windows, and use that to make a child of B. Now we can put it into our own program. We haven't done anything yet to connect its signaling to the Qt system.
This is probably more than you care about, but in case it's interesting to someone, here's the core of how it's done. I wrote a class called ForeignWindowEmbedder. Here's the method that gets our calculator window and re-parents it into a Qt widget:
# Embed the foreign window using its title
def embed_foreign_window(self):
self.hwnd = find_window_by_title(self.title)
if self.hwnd:
win32gui.SetParent(self.hwnd, int(self.winId()))
# Modify the foreign window's style
style = win32gui.GetWindowLong(self.hwnd,
win32con.GWL_STYLE)
# Remove title bar (caption)
new_style = style & ~win32con.WS_CAPTION
win32gui.SetWindowLong(self.hwnd,
win32con.GWL_STYLE, new_style)
# Move the foreign window to the 0, 0 corner of self
win32gui.SetWindowPos(self.hwnd, None, 0, 0, 0, 0,
win32con.SWP_NOSIZE | win32con.SWP_NOZORDER)
self.winId()is the Windows ID of our
ForeignWindowEmbedder
widget. With a Qt Widget, we would set its parent widget with setParent(). With a raw Windows object we use
win32gui.SetParent()instead.