gui_app.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. """
  2. Entry point for the MRI Sequence Interpreter GUI.
  3. Run from the repo root:
  4. python -m seq_interp.gui_app
  5. or:
  6. python seq_interp/gui_app.py
  7. Optionally pass a .seq file as the first CLI argument to pre-load it:
  8. python seq_interp/gui_app.py data/input/test1_full.seq
  9. """
  10. from __future__ import annotations
  11. import os
  12. import sys
  13. # Ensure the repo root (parent of seq_interp/) is importable regardless of
  14. # how the script is invoked.
  15. _here = os.path.dirname(os.path.abspath(__file__))
  16. _repo_root = os.path.dirname(_here)
  17. if _repo_root not in sys.path:
  18. sys.path.insert(0, _repo_root)
  19. import argparse
  20. from PySide6.QtWidgets import QApplication
  21. from seq_interp.src.gui.main_window import MainWindow
  22. def main() -> None:
  23. parser = argparse.ArgumentParser(
  24. description="MRI Sequence Interpreter — interactive GUI"
  25. )
  26. parser.add_argument(
  27. "seq_file", nargs="?", default=None,
  28. help="Optional .seq file to load on startup",
  29. )
  30. parser.add_argument(
  31. "--hw-config", default=None,
  32. help="Optional hardware config JSON to load on startup",
  33. )
  34. parser.add_argument(
  35. "--output-dir", default=None,
  36. help="Optional output directory",
  37. )
  38. args = parser.parse_args()
  39. app = QApplication(sys.argv)
  40. app.setApplicationName("MRI Sequence Interpreter")
  41. app.setOrganizationName("LF-MRI")
  42. # Qt6 / PySide6: high-DPI is enabled automatically — AA_UseHighDpiPixmaps
  43. # is deprecated and emits a DeprecationWarning; omit it.
  44. win = MainWindow()
  45. # Centre window on primary screen (MainWindow.__init__ sizes it already,
  46. # but doesn't centre)
  47. screen = app.primaryScreen()
  48. if screen is not None:
  49. ag = screen.availableGeometry()
  50. win.move(
  51. ag.x() + (ag.width() - win.width()) // 2,
  52. ag.y() + (ag.height() - win.height()) // 2,
  53. )
  54. # Pre-load files from CLI arguments if given
  55. if args.hw_config and os.path.isfile(args.hw_config):
  56. win._hw_config_path = os.path.abspath(args.hw_config)
  57. win._log(f"HW config pre-loaded: {win._hw_config_path}")
  58. if args.output_dir:
  59. win._output_dir = os.path.abspath(args.output_dir)
  60. win._log(f"Output dir: {win._output_dir}")
  61. if args.seq_file and os.path.isfile(args.seq_file):
  62. win._seq_path = os.path.abspath(args.seq_file)
  63. name = os.path.basename(win._seq_path)
  64. win._set_seq_state("selected", name)
  65. win._btn_run.setEnabled(True)
  66. win._log(f"Sequence pre-loaded: {win._seq_path}")
  67. win.show()
  68. sys.exit(app.exec())
  69. if __name__ == "__main__":
  70. main()