diff --git a/b_asic/scheduler_gui/compile.py b/b_asic/scheduler_gui/compile.py
new file mode 100644
index 0000000000000000000000000000000000000000..c3db4f7e2c80ae7b1eaf7d9a1204370317e8d242
--- /dev/null
+++ b/b_asic/scheduler_gui/compile.py
@@ -0,0 +1,216 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""B-ASIC Scheduler-gui Resource and Form Compiler Module.
+
+Compiles Qt5 resource and form files. Requires PySide2 or PyQt5 to be installed.
+If no arguments is given, the compiler search for and compiles all form (.ui)
+files.
+"""
+
+from qtpy import uic, API
+import sys
+import os
+import shutil
+import subprocess
+import argparse
+import b_asic.scheduler_gui
+import b_asic.scheduler_gui.logger as logger
+
+log = logger.getLogger()
+sys.excepthook = logger.handle_exceptions
+
+
+def _check_filenames(*filenames: str) -> None:
+    """Check if the filename(s) exist and if not, raise 'FileNotFoundError'
+    exception."""
+    for filename in filenames:
+        if not os.path.exists(filename):
+            raise FileNotFoundError(filename)
+
+
+def _check_qt_version() -> None:
+    """Checks if PySide2 or PyQt5 is installed, raises AssertionError otherwise."""
+    assert uic.PYSIDE2 or uic.PYQT5, 'PySide2 or PyQt5 need to be installed'
+
+
+def replace_qt_bindings(filename: str) -> None:
+    """Raplaces qt-binding api in 'filename' from PySide2/PyQt5 to qtpy."""
+    with open(f'{filename}', 'r') as file:
+        filedata = file.read()
+        filedata = filedata.replace('from PyQt5', 'from qtpy')
+        filedata = filedata.replace('from PySide2', 'from qtpy')
+    with open(f'{filename}', 'w') as file:
+        file.write(filedata)
+
+
+def compile_rc(*filenames: str) -> None:
+    """Compile resource file(s) given by 'filenames'. If no arguments are given,
+    the compiler will search for '*.qrc' files in 'icons\' folder and compile
+    accordingly."""
+    _check_qt_version()
+
+    def compile(filename: str = None) -> None:
+        outfile = f'{os.path.splitext(filename)[0]}_rc.py'
+        os_ = sys.platform
+
+        rcc = shutil.which('pyside2-rcc')
+        args = f'-g python -o {outfile} {filename}'
+        if rcc is None:
+            rcc = shutil.which('rcc')
+        if rcc is None:
+            rcc = shutil.which('pyrcc5')
+            args = f'-o {outfile} {filename}'
+        assert rcc, "PySide2 compiler failed, can't find rcc"
+
+        if os_.startswith("linux"):  # Linux
+            cmd = f'{rcc} {args}'
+            subprocess.call(cmd.split())
+
+        elif os_.startswith("win32"):  # Windows
+            # TODO: implement
+            log.error('Windows RC compiler not implemented')
+            raise NotImplementedError
+
+        elif os_.startswith("darwin"):  # macOS
+            # TODO: implement
+            log.error('macOS RC compiler not implemented')
+            raise NotImplementedError
+
+        else:  # other OS
+            log.error(f'{os_} RC compiler not supported')
+            raise NotImplementedError
+
+        replace_qt_bindings(outfile)  # replace qt-bindings with qtpy
+
+    if not filenames:
+        rc_files = [os.path.join(root, name)
+                    for root, dirs, files in os.walk('.')
+                        for name in files
+                            if name.endswith(('.qrc'))]
+        
+        for filename in rc_files:
+            compile(filename)
+        
+    else:
+        _check_filenames(*filenames)
+        for filename in filenames:
+            compile(filename)
+
+
+def compile_ui(*filenames: str) -> None:
+    """Compile form file(s) given by 'filenames'. If no arguments are given,
+    the compiler will search for '*.ui' files and compile accordingly."""
+    _check_qt_version()
+
+    def compile(filename: str) -> None:
+        dir, file = os.path.split(filename)
+        file, _ = os.path.splitext(file)
+        dir = dir if dir else '.'
+        outfile = f'{dir}/ui_{file}.py'
+
+        if uic.PYSIDE2:
+            os_ = sys.platform
+
+            uic_ = shutil.which('pyside2-uic')
+            args = f'-g python -o {outfile} {filename}'
+            if uic_ is None:
+                uic_ = shutil.which('uic')
+            if uic_ is None:
+                uic_ = shutil.which('pyuic5')
+                args = f'-o {outfile} {filename}'
+            assert uic_, "PySide2 compiler failed, can't find uic"
+
+            if os_.startswith("linux"):  # Linux
+                cmd = f'{uic_} {args}'
+                subprocess.call(cmd.split())
+
+            elif os_.startswith("win32"):  # Windows
+                # TODO: implement
+                log.error('Windows UI compiler not implemented')
+                raise NotImplementedError
+
+            elif os_.startswith("darwin"):  # macOS
+                # TODO: implement
+                log.error('macOS UI compiler not implemented')
+                raise NotImplementedError
+
+            else:  # other OS
+                log.error(f'{os_} UI compiler not supported')
+                raise NotImplementedError
+
+        else:   # uic.PYQT5
+            from qtpy.uic import compileUi
+            with open(outfile, 'w') as ofile:
+                compileUi(filename, ofile)
+
+        replace_qt_bindings(outfile)  # replace qt-bindings with qtpy
+
+    if not filenames:
+        ui_files = [os.path.join(root, name)
+                    for root, dirs, files in os.walk('.')
+                        for name in files
+                            if name.endswith(('.ui'))]
+        for filename in ui_files:
+            compile(filename)
+    else:
+        _check_filenames(*filenames)
+        for filename in filenames:
+            compile(filename)
+
+
+def compile_all():
+    """The compiler will search for '*.qrc* resource files in 'icons\' folder
+    and for '*.ui' form files and compile accordingly."""
+    compile_rc()
+    compile_ui()
+
+
+if __name__ == '__main__':
+    ver = b_asic.scheduler_gui.__version__
+    descr = __doc__
+
+    parser = argparse.ArgumentParser(description=f'{descr}',
+                                     formatter_class=argparse.RawTextHelpFormatter)
+
+    parser.add_argument('-v', '--version',
+                        action='version',
+                        version=f'%(prog)s v{ver}')
+
+    if sys.version_info >= (3, 8):
+        parser.add_argument('--ui',
+                            metavar='<file>',
+                            action='extend',
+                            nargs='*',
+                            help="compile form file(s) if <file> is given, otherwise search\n"
+                            "for all form (*.ui) files and compile them all (default)")
+        parser.add_argument('--rc',
+                            metavar='<file>',
+                            action='extend',
+                            nargs='*',
+                            help="compile resource file(s) if <file> is given, otherwise\n"
+                            "search for all resource (*.ui) files and compile them all")
+    else:
+        parser.add_argument('--ui',
+                            metavar='<file>',
+                            action='append',
+                            help="compile form file")
+        parser.add_argument('--rc',
+                            metavar='<file>',
+                            action='append',
+                            help="compile resource file")
+
+    parser.add_argument('--all',
+                        action='store_true',
+                        help="search and compile all resource and form file(s)")
+
+    if len(sys.argv) == 1:
+        compile_ui()
+
+    args = parser.parse_args()
+
+    if args.ui is not None:
+        compile_ui(*args.ui)
+    if args.rc is not None:
+        compile_rc(*args.rc)
+    if args.all:
+        compile_all()
diff --git a/b_asic/scheduler_gui/main_window.py b/b_asic/scheduler_gui/main_window.py
index e752a0eb4299a551d130c4872560c7f84fd696be..29ef7253beefd0dbe253084017392f3dd18779ad 100644
--- a/b_asic/scheduler_gui/main_window.py
+++ b/b_asic/scheduler_gui/main_window.py
@@ -47,10 +47,8 @@ from b_asic.schedule import Schedule
 from b_asic.scheduler_gui.graphics_axes_item import GraphicsAxesItem
 from b_asic.scheduler_gui.graphics_component_item import GraphicsComponentItem
 from b_asic.scheduler_gui.graphics_graph_item import GraphicsGraphItem
-
-# if sys.version_info >= (3, 9):
-#     List = list
-#     #Dict = dict
+sys.path.insert(0, "icons/")  # Needed for *.rc.py files in ui_main_window
+from b_asic.scheduler_gui.ui_main_window import Ui_MainWindow
 
 log = logger.getLogger()
 sys.excepthook = logger.handle_exceptions
@@ -78,43 +76,6 @@ if __debug__:
         log.debug("PyQt version:             {}".format(PYQT_VERSION_STR))
     log.debug("QtPy version:             {}".format(qtpy.__version__))
 
-    # Autocompile the .ui form to a python file.
-    try:  # PyQt5, try autocompile
-        from qtpy.uic import compileUiDir
-
-        compileUiDir(".", map=(lambda dir, file: (dir, "ui_" + file)))
-    except:
-        try:  # PySide2, try manual compile
-            import subprocess
-
-            os_ = sys.platform
-            if os_.startswith("linux"):
-                cmds = ["pyside2-uic -o ui_main_window.py main_window.ui"]
-                for cmd in cmds:
-                    subprocess.call(cmd.split())
-            else:
-                # TODO: Implement (startswith) 'win32', 'darwin' (MacOs)
-                raise SystemExit
-        except:  # Compile failed, look for pre-compiled file
-            try:
-                from b_asic.scheduler_gui.ui_main_window import Ui_MainWindow
-            except:  # Everything failed, exit
-                log.exception("Could not import 'Ui_MainWindow'.")
-                log.exception(
-                    "Can't autocompile under",
-                    QT_API,
-                    "eviroment. Try to manual compile 'main_window.ui' to"
-                    " 'ui/main_window_ui.py'",
-                )
-                os._exit(1)
-
-
-sys.path.insert(
-    0, "icons/"
-)  # Needed for the compiled '*_rc.py' files in 'ui_*.py' files
-from b_asic.scheduler_gui.ui_main_window import (
-    Ui_MainWindow,
-)  # Only availible when the form (.ui) is compiled
 
 # The following QCoreApplication values is used for QSettings among others
 QCoreApplication.setOrganizationName("Linöping University")