Search code examples
pythonmatplotlibpywin32

How to uniquely get the win32api/win32gui figure handle from the matplotlib figure object


I wonder what is the best way to uniquely obtain the win32gui's window handle given the matplotlib's figure object.

I know I can find it based on the window title with win32gui.FindWindow()

import matplotlib.pyplot as plt
import win32gui

fig = plt.figure()
my_title = 'My Figure'
fig.canvas.manager.window.title(my_title)
hdl = win32gui.FindWindow(None, my_title)
print(hdl)

>>> 7735822 (just an arbitrary number here)

but this method fails if I have more than one window with the same title (the reasons why to do so are out of the question), since FindWindow seems to return only the first result that matches the search:

fig1 = plt.figure()
fig2 = plt.figure()
my_title = 'My Figure'
fig1.canvas.manager.window.title(my_title)
fig2.canvas.manager.window.title(my_title)  # Both figures have same window title
hdl = win32gui.FindWindow(None, my_title)
print(hdl)

>>> 6424880 (just another one arbitrary number here)

In the second example at least it would be nice if hdl were a list of handles with all matches found.

I seems logical to me that if I have the specific python object pointing to the figure, there must be a unique way to get the win32gui window handle, but I can't find the answer anywhere. Something like:

fig = plt.figure()
hdl = fig.get_w32_handle()
# or
hdl = win32gui.GetWindowFromID(id(fig))

Solution

  • I found the answer here after searching again by using the 'Tkinter' keyword rather than 'matplotlib'

    Basically I can get the Windows handle (in hexadecimal) with the frame() method and convert it do decimal to then use it with the win32 api:

    import matplotlib.pyplot as plt
    import win32gui
    
    fig1 = plt.figure()
    fig2 = plt.figure()
    
    my_title = 'My Figure'
    fig1.canvas.manager.window.title(my_title)
    fig2.canvas.manager.window.title(my_title)  # Both figures have same window title
    
    hdl1 = int(fig1.canvas.manager.window.frame(), 16)  # Hex -> Dec
    hdl2 = int(fig2.canvas.manager.window.frame(), 16)  
    
    print(hdl1, ':', win32gui.GetWindowText(hdl1))
    print(hdl2, ':', win32gui.GetWindowText(hdl2))
    
    
    >>> 199924 : My Figure
    >>> 396520 : My Figure