Cross-Platform module which allows to manage window areas (position and size) and all their properties, as well as any rectangular area on screen.
PyWinBox is similar to PyGame.Rect object, but extended with some useful features:
- Supports window areas, even if the window belongs to a foreign application
- Invokes custom callbacks whenever any area property is queried or changed
- Works in multi-monitor setups
- Manages both Rect and Box structs
- Provides convenient named-tuple structs to ease handling geometry properties and their attributes
You just need to instantiate the PyWinBox class, passing custom callbacks to be called when any property is
queried (onQuery) or set (onSet).
myBox = pywinbox.PyWinBox(onQuery=customOnQuery, onSet=customOnSet)For rectangular areas, it is necessary to pass custom (not default) callbacks which actually manage the box struct values, or the struct will be empty and/or useless.
To manage window areas, you need to also pass the window handle when instantiating the class.
| Platform | Handle format |
|---|---|
| MS-Windows | int (window id) or str (as returned by e.g. PyQt's winId() method) |
| Linux | int (window id) or X-Window object |
| macOS / foreign window | tuple of strings (appName, windowTitle) — to manage a window from another application |
| macOS / own window | NSWindow object — to manage your own application window |
Search for cross-platform modules if you need a cross-platform handle. For instance, you can obtain handles using PyWinCtl's
getHandle(),getAppName()ortitlemethods.
When a window handle is provided, you can use the built-in default methods by passing None:
| Callback | Behavior |
|---|---|
| default onQuery | Updates the window position and size values when any property is queried |
| default onSet | Moves and/or resizes the window when any property is set |
myBox = pywinbox.PyWinBox(onQuery=None, onSet=None, handle=windowHandle)You can define and pass your own callback functions if you need to perform additional actions on these events.
Important: If your custom functions do not properly retrieve or set the actual window position and size, the information contained in the PyWinBox class — and returned by all properties — will likely become obsolete.
You can call the built-in methods from within your custom callbacks to keep the struct in sync:
def customOnQuery():
currBox = myBox.onQuery() # Retrieves the current window's box
# ... do your stuff ...
return currBox
def customOnSet(newBox: Box):
myBox.onSet(newBox) # Actually moves/resizes the window
# ... do your stuff ...
myBox = pywinbox.PyWinBox(onQuery=customOnQuery, onSet=customOnSet, handle=windowHandle)All position and size properties are readable and writable. Setting any property will trigger the onSet callback;
reading any property will trigger the onQuery callback.
| Properties | Description |
|---|---|
left, top, right, bottom |
Individual edge coordinates |
width, height |
Dimensions |
size |
(width, height) |
topleft, topright, bottomleft, bottomright |
Corner coordinates as (x, y) |
midtop, midleft, midbottom, midright |
Mid-edge coordinates as (x, y) |
center |
Center point as (x, y) |
centerx, centery |
Individual center coordinates |
box |
(left, top, width, height) |
rect |
(left, top, right, bottom) |
These named tuples provide a convenient way to manage and pass geometry values throughout your code:
| Struct | Fields |
|---|---|
Box |
left, top, width, height |
Rect |
left, top, right, bottom |
Size |
width, height |
Point |
x, y |
To install this module on your system, you can use pip:
python -m pip install pywinbox
or using uv:
uv add pywinbox
Alternatively, you can download the wheel file (.whl) available in the Download page and the dist folder, and run this (don't forget to replace 'x.x.xx' with the proper version number):
python -m pip install PyWinBox-x.x.xx-py3-none-any.whl
You may want to add --force-reinstall to be sure you are installing the right dependencies version.
Then, you can use it on your own projects just importing it:
import pywinboxIn case you have a problem, comments or suggestions, do not hesitate to open issues on the project homepage.
If you want to use this code or contribute, you can either:
- Create a fork of the repository, or
- Download the repository, uncompress, and open it on your IDE of choice (e.g. PyCharm)
Be sure you install all dev dependencies by running:
uv sync
or
python -m venv .venv
python -m pip install -e . --group=dev
To test this module on your own system, cd to the tests folder and run:
uv run test_pywinbox.py
For macOS NSWindow, you can also test using:
uv run test_MacNSBox.py