Display a message box with Python without using a non-standard library or other dependency (Windows)

I’ve been using Python a lot more lately and have discovered some pretty interesting things – one of which I want to share here. A recent project had a requirement for a Python script that would be deployed to users’ machines as a scheduled task, triggered on login to run at a set interval every n minutes. Normally, the script executes silently, without the need for any user interaction. However, there may be an occasional error or warning condition I want to surface to the user so that they may take the appropriate action. Because the script runs as a background task, without opening a command line window, there is no standard output to which print() statements will be displayed to the user and there is no UI to alert the user.

If a UI is needed in Python, libraries like Qt, Tk, and many others get the job done nicely, but I didn’t want any additional dependencies. This script needs to maximize portability across a wide array of target machines, so sticking to the default libraries as much as possible was my goal. I only needed a basic message box to display the error or warning details with an “OK” button to acknowledge the user saw the alert – importing one of the GUI libraries would be too complex of a solution in my opinion. Because all of the target machines will be running Windows, I can directly use OS-specific features to render a message box using the ctypes library and the Windows API. Ctypes allows Python code to directly call various libraries, written in C, included with Windows.

Here is the sample code – you can also view as a GitHub Gist.

import ctypes

def main():
    WS_EX_TOPMOST = 0x40000
    windowTitle = "Python Windows Message Box Test"
    message = "Hello, world! This Message box was created by calling the Windows API using the ctypes library."

    # display a message box; execution will stop here until user acknowledges
    ctypes.windll.user32.MessageBoxExW(None, message, windowTitle, WS_EX_TOPMOST)

    print("User clicked OK.")

if __name__ == "__main__":
    main()

Here’s what’s happening in the script: the ctypes library is imported first, and inside the main() method, a variable named WX_EX_TOPMOST is assigned a hexadecimal value of 0x40000. The variable name is taken from the different window styles in the Windows API, and “0x40000” is a constant value that will apply a “top most” window style to the dialog box. This will set its z-order so that the message box is on top of all other open windows. The ctypes library exposes methods which essentially wrap up calls to the Windows API functions like MessageBoxExW, making interacting with the API easy. MessageBoxExW() is called, passing in None for the owner window handle (so the message box has no parent window), the message to display, the window title, and the window style.

When the script is run, a Windows MessageBox is displayed. Clicking OK will resume execution of the script.

8 thoughts on “Display a message box with Python without using a non-standard library or other dependency (Windows)

    1. This was the perfect solution for me: all target machines are running Windows, and I only needed to show a message box during infrequent error conditions. A GUI library or framework would have been way overkill.

      Like

    1. Thank you for catching that! The correct value for the topmost window style is β€œ0x40000” – this was correct in my sample code block, but incorrect in the body text of this post. I have corrected those typos and re-published.

      Like

      1. is there an equally simple way to get user input and display it in a label? I am having a hard time with the tkinter way

        Like

Leave a comment