diff --git a/qt/applications/workbench/workbench/app/mainwindow.py b/qt/applications/workbench/workbench/app/mainwindow.py
index d376a13aa49a53f71c35dcadc029b48a6a5652b8..8910a0f260c2d32d474df1d5ab33e21575619e7a 100644
--- a/qt/applications/workbench/workbench/app/mainwindow.py
+++ b/qt/applications/workbench/workbench/app/mainwindow.py
@@ -10,6 +10,7 @@
 """
 Defines the QMainWindow of the application and the main() entry point.
 """
+import builtins
 import os
 
 from mantid.api import FrameworkManager
@@ -39,6 +40,7 @@ from workbench.config import CONF  # noqa
 from workbench.plotting.globalfiguremanager import GlobalFigureManager  # noqa
 from workbench.utils.windowfinder import find_all_windows_that_are_savable  # noqa
 from workbench.utils.workspacehistorygeneration import get_all_workspace_history_from_ads  # noqa
+from workbench.utils.io import input_qinputdialog
 from workbench.projectrecovery.projectrecovery import ProjectRecovery  # noqa
 from workbench.utils.recentlyclosedscriptsmenu import RecentlyClosedScriptsMenu # noqa
 from mantidqt.utils.asynchronous import BlockingAsyncTaskWithCallback  # noqa
@@ -197,6 +199,8 @@ class MainWindow(QMainWindow):
         self.readSettings(CONF)
         self.config_updated()
 
+        self.override_python_input()
+
     def post_mantid_init(self):
         """Run any setup that requires mantid
         to have been initialized
@@ -752,3 +756,7 @@ class MainWindow(QMainWindow):
         for widget in self.widgets:
             if hasattr(widget, 'writeSettings'):
                 widget.writeSettings(settings)
+
+    def override_python_input(self):
+        """Replace python input with a call to a qinputdialog"""
+        builtins.input = QAppThreadCall(input_qinputdialog)
diff --git a/qt/applications/workbench/workbench/app/start.py b/qt/applications/workbench/workbench/app/start.py
index c090ed19e0ae2be8e39ba26ccc80d834c327c412..78ac02f7a79a413a16408799af87ecbef66a5e7c 100644
--- a/qt/applications/workbench/workbench/app/start.py
+++ b/qt/applications/workbench/workbench/app/start.py
@@ -15,6 +15,7 @@ from functools import partial
 from mantid.api import FrameworkManagerImpl
 from mantid.kernel import ConfigService, UsageService, version_str as mantid_version_str
 from mantidqt.utils.qt import plugins
+from mantidqt.utils.qt.qappthreadcall import QAppThreadCall
 
 # Find Qt plugins for development builds on some platforms
 plugins.setup_library_paths()
@@ -28,6 +29,7 @@ from workbench.app.resources import qCleanupResources  # noqa
 from workbench.config import APPNAME, ORG_DOMAIN, ORGANIZATION  # noqa
 from workbench.plugins.exception_handler import exception_logger  # noqa
 from workbench.widgets.about.presenter import AboutPresenter  # noqa
+from workbench.utils.io import input_qinputdialog
 
 # Constants
 SYSCHECK_INTERVAL = 50
diff --git a/qt/applications/workbench/workbench/test/mainwindowtest.py b/qt/applications/workbench/workbench/test/mainwindowtest.py
index 2f9b1e7fe1f4f55da2b333c09ea32bb4ce049b28..233dd8a7953b8ca17a38389e54d981f80e4261da 100644
--- a/qt/applications/workbench/workbench/test/mainwindowtest.py
+++ b/qt/applications/workbench/workbench/test/mainwindowtest.py
@@ -337,6 +337,14 @@ class MainWindowTest(unittest.TestCase):
         }
         self.assertDictEqual(expected_interfaces, all_interfaces)
 
+    @patch('workbench.app.mainwindow.input_qinputdialog')
+    def test_override_python_input_replaces_input_with_qinputdialog(self, mock_input):
+        self.main_window.override_python_input()
+
+        input("prompt")
+
+        mock_input.assert_called_with("prompt")
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/qt/applications/workbench/workbench/utils/io.py b/qt/applications/workbench/workbench/utils/io.py
new file mode 100644
index 0000000000000000000000000000000000000000..51ee9a69a37dd4c87ce3b60ae082f1c6ff325fbc
--- /dev/null
+++ b/qt/applications/workbench/workbench/utils/io.py
@@ -0,0 +1,24 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright © 2021 ISIS Rutherford Appleton Laboratory UKRI,
+#   NScD Oak Ridge National Laboratory, European Spallation Source,
+#   Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantidworkbench package
+from qtpy.QtWidgets import QInputDialog
+
+
+def input_qinputdialog(prompt: str = "") -> str:
+    """
+    Raises a QInputDialog with a given prompt and returns the user input as a string.
+    If the user cancels the dialog, a RuntimeError is raised.
+    Intended to be used to override python's `input` function to be more user friendly.
+    """
+    dlg = QInputDialog()
+    dlg.setInputMode(QInputDialog.TextInput)
+    dlg.setLabelText(str(prompt) if prompt is not None else "")
+    accepted = dlg.exec_()
+    if accepted:
+        return dlg.textValue()
+    else:
+        raise RuntimeError("User input request cancelled")