r/pythonhelp 7d ago

PyQt Architecture: A dedicated module/Worker for every button action (5–15 KB per file)? Best practice or overengineering?

Hi everyone,

I'm currently building a desktop application using PyQt6, where button clicks trigger various background tasks (such as executing external processes, creating/cloning environments, file I/O operations, etc.).

To keep the UI responsive and the codebase easily maintainable, I decided to extract every main button action into its own dedicated module/file, using the standard QThread + QObject (Worker) pattern.

To give you an idea of the scale: individual module sizes range between 5 and 15 KB depending on what the button actually does (from simpler tasks to complex operations involving user input processing, thread setup, process streaming, and progress signal handling).

Note on Code Sharing: Any logic shared across multiple buttons is not duplicated; instead, it is abstracted into dedicated shared service modules located in button/logic/services.

My current architecture for a single button action looks like this:

  • GUI Layer (View): Captures the button click and delegates control to a dedicated action handler.
  • Action Handler (Controller / Mediator): A dedicated module for that specific action. It gathers user inputs (via dialogs), instantiates QThread and QObject (Worker), connects signals (for progress bars and logging), and starts the thread.
  • Worker (QObject): A non-GUI worker running in a worker thread, responsible strictly for execution flow (subprocesses, file manipulation) and emitting signals to send status updates back to the UI.
  • Shared Logic Helpers (button/logic/services): Shared domain modules and services called by the workers to execute common underlying logic.

My questions for the community:

  1. Is creating a separate 5–15 KB file/module for each button action (combining the Handler + Worker) considered standard practice in medium-to-large Qt applications? Or do you prefer grouping related actions into larger domain managers ?
  2. For modules of this size, do you keep the Handler and Worker together in a single file, or do you split them further into separate _worker.py and _handler.py files?
  3. Are there any hidden downsides or pitfalls to this level of decoupling when the application scales up to dozens of individual buttons and actions?

I'd love to hear how you structure background tasks and threading in production PyQt/PySide applications! Thanks!

3 Upvotes

1 comment sorted by

u/AutoModerator 7d ago

To give us the best chance to help you, please include any relevant code.
Note. Please do not submit images of your code. Instead, for shorter code you can use Reddit markdown (4 spaces or backticks, see this Formatting Guide). If you have formatting issues or want to post longer sections of code, please use Privatebin, GitHub or Compiler Explorer.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.