-
-
Notifications
You must be signed in to change notification settings - Fork 11
✨Simulation view redesign with simulation run add, edit, import, export and execution functionality #522
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
burgholzer
merged 89 commits into
munich-quantum-toolkit:main
from
TooMuchDakka:simulation-view-redesign
Feb 6, 2026
Merged
✨Simulation view redesign with simulation run add, edit, import, export and execution functionality #522
Changes from all commits
Commits
Show all changes
89 commits
Select commit
Hold shift + click to select a range
1bf9114
Basic prototype of tabs and simulation run widget
TooMuchDakka 33c1e54
Added quantum register search controls and fixed qubits toggle functi…
TooMuchDakka 9008f95
Added validator for quantum register contents input fields. Added qub…
TooMuchDakka 7f103dc
Removed some unnecessary scroll areas between simulation run widget a…
TooMuchDakka 146b2fb
Added comment regarding potential rendering issues when using widgets…
TooMuchDakka 7be1d58
Basic prototype using model-view architecture to display simulation r…
TooMuchDakka 9abbe44
Basic still faulty print of quantum register contents in QStyledItemD…
TooMuchDakka 9f0b759
Split model and styled item delegate as well as simulation run edit d…
TooMuchDakka 45e6a91
Add logic for simulation run list controls as well as for simulation …
TooMuchDakka e41054a
Added icons to buttons of simulation run overview dialog
TooMuchDakka 74f39cd
Fixed height calculation for simulation run cards
TooMuchDakka 3051605
Replaced InputOutputStateMapping with SimulationRunModel containing f…
TooMuchDakka 04ee7e2
Refactored existing simulation run editor dialog to be opened when cl…
TooMuchDakka a5e87fa
Internal simulation run model is now updated in edit dialog and added…
TooMuchDakka dedb20a
Added controls to init and reset expected output state in simulation …
TooMuchDakka 3775c90
Added quantum register layout info label, quantum register content va…
TooMuchDakka 8e9899f
Invalid values for qubits of quantum register will no disable control…
TooMuchDakka 823d9b9
Added warnings for switching between simulation run tabs widget tabs …
TooMuchDakka b28c0a0
Implemented basic thread communication between UI and simulation run …
TooMuchDakka 067fb59
Added progress controls and cancellation controls to qt simulation ru…
TooMuchDakka ce68abe
Refactored simulation run overview delegate by moving shared code int…
TooMuchDakka 4f29d10
Added simulation run execution styled item delegate and small bugfixe…
TooMuchDakka fa15d2c
Refactored all simulation run combinations generator into worker inst…
TooMuchDakka 34ba955
Small improvements helping to reduce a complete hang of the GUI added…
TooMuchDakka a11727c
All input states generator now used QReadWriteLock instead of QMutex.…
TooMuchDakka e238121
mend
TooMuchDakka 50fb7a8
Simulation run dialog closeEvent is now correctly handled and correct…
TooMuchDakka 6497271
Edit dialog of simulation run now uses copy of reference simulation r…
TooMuchDakka e3bc0b6
Basic setup of ijson library to allow for import of simulation runs f…
TooMuchDakka f83c6f1
Added tool tip containing information about expected .json file forma…
TooMuchDakka fe63c77
Reworked acknowledgement of batch data to worker by introducing separ…
TooMuchDakka 4d26730
Refactored some shared worker functionality into shared base class
TooMuchDakka 2a687f4
Added descriptive comments about worker-object and QThread relationsh…
TooMuchDakka 7cd18b8
Refactored shared logging and message box functionality to helper cla…
TooMuchDakka 1e8aec3
Refactored simulation run export dialog to use reusable BaseProgressD…
TooMuchDakka 5891e8e
Refactored simulation run import worker/dialog to use shared worker/p…
TooMuchDakka 6b1e472
Simulation run execution worker and dialog are now using batch instea…
TooMuchDakka d7c2640
Simplified input state generation loop in simulatin run generator worker
TooMuchDakka 0b86952
Split __init__ function creating dialog controls into separate functi…
TooMuchDakka 0eb4e74
All simulation run dialogs are now centered when opened, added functi…
TooMuchDakka 2c2ebb6
Simulation run editor will now close when any of the required QtWidge…
TooMuchDakka 7d14e7a
Refactoring of simulation_view folder by creating subfolders to group…
TooMuchDakka a8f02ca
QuantumCircuitSimulationDialog is now opened using offically recommen…
TooMuchDakka 045593d
Simulation run styled item delegate now draws expected and actual qua…
TooMuchDakka 3adb48d
Simulation run execution dialog listview now also lists help text reg…
TooMuchDakka cd04d5a
Simulation run editor now displays both the expected as well as the a…
TooMuchDakka 4e9f401
Quantum register and qubit search functionality now also includes exp…
TooMuchDakka 2f56a45
Improvided error reporting on expected batch data type missmatch
TooMuchDakka 0835ca6
Unified checks for required QtWidgets in all dialogs and renamed opti…
TooMuchDakka 0f966ff
Added reject() implementation to handle correctly reuse cancellation …
TooMuchDakka 6dcbdb9
Associated SyReC program is now also serialized into exported JSON da…
TooMuchDakka e2f9fb4
Fixed enabled state of simulation run modification buttons when cance…
TooMuchDakka c217ec7
Added optional typing-extensions project dependency
TooMuchDakka 44bde58
Export to file now allows for file creation, fixed display of runtime…
TooMuchDakka e118494
Applied CodeRabbit code review suggestions
TooMuchDakka 3852240
Exporting stringified SyReC programs is only supported in quantum cir…
TooMuchDakka d4b8bb0
Further CodeRabbit code review suggestions
TooMuchDakka 75198a1
Added pyqtSlot() decorator to simulation run editor dialog
TooMuchDakka 3eb25c3
Fixed decorator signature missmatch during expected output state miss…
TooMuchDakka 380d3b0
Removed unneeded regex in simulation run editor dialog
TooMuchDakka 5a8fc84
Added missing return type to __init__ constructors of newly added cla…
TooMuchDakka a1f384e
Further CodeRabbit suggestions that unifies worker and worker thread …
TooMuchDakka 9b40e65
Added missing @override decorators to closeEvent and reject functions…
TooMuchDakka e7880a8
Removed redundant name parameter from signal declarations and smaller…
TooMuchDakka 9259c47
Added prototype refactoring of cancellable base worker to support pro…
TooMuchDakka fd8dda5
Reworked all input states genertion worker to use new producer worker…
TooMuchDakka 76dc5a4
Refactored simulation run json import worker and dialog to use produc…
TooMuchDakka a33c6d2
Refactored simulation run json exportt worker and dialog to use produ…
TooMuchDakka 4d04744
Moved QtSimulationRunModel property shared by all simulation run dial…
TooMuchDakka bd3b1af
Added import failure and default fallback for ijson package
TooMuchDakka 81aa987
Added some doc strings and refactored some shared functionality in si…
TooMuchDakka 9600082
Simulation run execution mode can now be selected via dropdown. Execu…
TooMuchDakka 800fba9
Added some docstrings and marked all protected/private instance varia…
TooMuchDakka 8ea4637
Fixed various smaller selection change bugs that effected the simulat…
TooMuchDakka 859efae
Added back missing edited simulation run model index instance variabl…
TooMuchDakka 92eca56
Merge of changes from main branch
TooMuchDakka 0fe9463
Refactored some class variables to instance variable in SyReCEditor p…
TooMuchDakka 5357109
Added temporary workaround for quantum registers of ancillary variabl…
TooMuchDakka 6c9fc03
CodeRabbit trivial or minor issue suggestions
TooMuchDakka 3b49ad7
Enabling simulation run execution controls in load from file tab now …
TooMuchDakka 58bca5b
Simulation run json export worker now puts element in queue before em…
TooMuchDakka 4916ee5
Further CodeRabbit suggestions
TooMuchDakka 348ad2a
CodeRabbit suggestions to replace positional boolean arguments with k…
TooMuchDakka b8bc8ce
Transformed some boolean positional arguments to keyword only ones an…
TooMuchDakka 63ae6c7
Transformed some boolean positional arguments to keyword only ones an…
TooMuchDakka f03adbe
Fixed some invalid types in typing.cast calls as well as wrong type h…
TooMuchDakka 61181f4
Removed some dead code and simplified match check for quantum registe…
TooMuchDakka c5c204b
Updated parent widget constructor argument type signaturet in LineEdi…
TooMuchDakka f2b0ab3
Added missing return type to LineEditWithDynamicWidth constructor
TooMuchDakka File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| # Copyright (c) 2023 - 2026 Chair for Design Automation, TUM | ||
| # Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH | ||
| # All rights reserved. | ||
| # | ||
| # SPDX-License-Identifier: MIT | ||
| # | ||
| # Licensed under the MIT License | ||
|
|
||
| import logging | ||
| from typing import Final | ||
|
|
||
| DEFAULT_LOGGER_NAME: Final[str] = "syrec-console-logger" | ||
|
|
||
|
|
||
| def configure_default_console_logger() -> None: | ||
| # For supported log message formats (see https://docs.python.org/3/library/logging.html#formatter-objects) | ||
| logger = logging.getLogger(DEFAULT_LOGGER_NAME) | ||
| if logger.handlers: | ||
| return | ||
|
|
||
| handler = logging.StreamHandler() | ||
| handler.setFormatter( | ||
| logging.Formatter( | ||
| "%(asctime)s-%(levelname)s-[%(filename)s:%(lineno)s - %(funcName)20s()]-%(message)s", | ||
| datefmt="%H:%M:%S", | ||
| ) | ||
| ) | ||
| logger.addHandler(handler) | ||
| logger.setLevel(logging.DEBUG) | ||
|
|
||
|
|
||
| def log_debug_to_console( | ||
| info_msg: str, num_additionally_skipped_stack_frames_starting_from_caller_function: int = 0 | ||
| ) -> None: | ||
| logger = logging.getLogger(DEFAULT_LOGGER_NAME) | ||
| # We do not want to log the origin of the helper function but of the caller of the function itself. | ||
| # The origin of the log entry is set to the stack frame of the caller but can be advanced further up in the stack trace | ||
| logger.debug(msg=info_msg, stacklevel=(2 + num_additionally_skipped_stack_frames_starting_from_caller_function)) | ||
|
coderabbitai[bot] marked this conversation as resolved.
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
|
|
||
| def log_info_to_console( | ||
| info_msg: str, num_additionally_skipped_stack_frames_starting_from_caller_function: int = 0 | ||
| ) -> None: | ||
| logger = logging.getLogger(DEFAULT_LOGGER_NAME) | ||
| # We do not want to log the origin of the helper function but of the caller of the function itself. | ||
| # The origin of the log entry is set to the stack frame of the caller but can be advanced further up in the stack trace | ||
| logger.info(msg=info_msg, stacklevel=(2 + num_additionally_skipped_stack_frames_starting_from_caller_function)) | ||
|
|
||
|
|
||
| def log_warning_to_console( | ||
| warn_msg: str, num_additionally_skipped_stack_frames_starting_from_caller_function: int = 0 | ||
| ) -> None: | ||
| logger = logging.getLogger(DEFAULT_LOGGER_NAME) | ||
| # We do not want to log the origin of the helper function but of the caller of the function itself. | ||
| # The origin of the log entry is set to the stack frame of the caller but can be advanced further up in the stack trace | ||
| logger.warning(msg=warn_msg, stacklevel=(2 + num_additionally_skipped_stack_frames_starting_from_caller_function)) | ||
|
|
||
|
|
||
| def log_error_to_console( | ||
| err_msg: str, num_additionally_skipped_stack_frames_starting_from_caller_function: int = 0 | ||
| ) -> None: | ||
| logger = logging.getLogger(DEFAULT_LOGGER_NAME) | ||
| # We do not want to log the origin of the helper function but of the caller of the function itself. | ||
| # The origin of the log entry is set to the stack frame of the caller but can be advanced further up in the stack trace | ||
| logger.error(msg=err_msg, stacklevel=(2 + num_additionally_skipped_stack_frames_starting_from_caller_function)) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| # Copyright (c) 2023 - 2026 Chair for Design Automation, TUM | ||
| # Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH | ||
| # All rights reserved. | ||
| # | ||
| # SPDX-License-Identifier: MIT | ||
| # | ||
| # Licensed under the MIT License | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import sys | ||
| from enum import Enum | ||
|
|
||
| from PyQt6 import QtWidgets | ||
|
|
||
| if sys.version_info >= (3, 11): | ||
| from typing import assert_never | ||
| else: | ||
| from typing_extensions import assert_never | ||
|
|
||
| from .logger_utils import log_debug_to_console, log_error_to_console, log_info_to_console, log_warning_to_console | ||
|
|
||
|
|
||
| class MessageBoxType(Enum): | ||
| QUESTION = 0 | ||
| INFO = 1 | ||
| WARNING = 2 | ||
| ERROR = 3 | ||
|
|
||
|
|
||
| def show_and_request_ok_in_optionally_cancellable_notification( | ||
| message_box_type: MessageBoxType, | ||
| message_box_parent: QtWidgets.QWidget, | ||
| message_box_title: str, | ||
| message_box_content: str, | ||
| *, | ||
| is_cancellable: bool, | ||
| log_contents: bool = True, | ||
| ) -> bool: | ||
| clicked_message_box_button: QtWidgets.QMessageBox.StandardButton | None = None | ||
| match message_box_type: | ||
| case MessageBoxType.QUESTION: | ||
| if log_contents: | ||
| log_debug_to_console( | ||
| f"{message_box_title} - {message_box_content}", | ||
| num_additionally_skipped_stack_frames_starting_from_caller_function=1, | ||
| ) | ||
|
|
||
| clicked_message_box_button = QtWidgets.QMessageBox.question( | ||
| message_box_parent, | ||
| message_box_title, | ||
| message_box_content, | ||
| buttons=_get_buttons_for_message_box_type(message_box_type, is_cancellable=is_cancellable), | ||
| defaultButton=_get_default_button_for_message_box_type(message_box_type, is_cancellable=is_cancellable), | ||
| ) | ||
| return _check_whether_message_ok_was_clicked(message_box_type, clicked_message_box_button) | ||
| case MessageBoxType.INFO: | ||
| if log_contents: | ||
| log_info_to_console( | ||
| f"{message_box_title} - {message_box_content}", | ||
| num_additionally_skipped_stack_frames_starting_from_caller_function=1, | ||
| ) | ||
|
|
||
| clicked_message_box_button = QtWidgets.QMessageBox.information( | ||
| message_box_parent, | ||
| message_box_title, | ||
| message_box_content, | ||
| buttons=_get_buttons_for_message_box_type(message_box_type, is_cancellable=is_cancellable), | ||
| defaultButton=_get_default_button_for_message_box_type(message_box_type, is_cancellable=is_cancellable), | ||
| ) | ||
| return _check_whether_message_ok_was_clicked(message_box_type, clicked_message_box_button) | ||
| case MessageBoxType.WARNING: | ||
| if log_contents: | ||
| log_warning_to_console( | ||
| f"{message_box_title} - {message_box_content}", | ||
| num_additionally_skipped_stack_frames_starting_from_caller_function=1, | ||
| ) | ||
|
|
||
| clicked_message_box_button = QtWidgets.QMessageBox.warning( | ||
| message_box_parent, | ||
| message_box_title, | ||
| message_box_content, | ||
| buttons=_get_buttons_for_message_box_type(message_box_type, is_cancellable=is_cancellable), | ||
| defaultButton=_get_default_button_for_message_box_type(message_box_type, is_cancellable=is_cancellable), | ||
| ) | ||
| return _check_whether_message_ok_was_clicked(message_box_type, clicked_message_box_button) | ||
| case MessageBoxType.ERROR: | ||
| if log_contents: | ||
| log_error_to_console( | ||
| f"{message_box_title} - {message_box_content}", | ||
| num_additionally_skipped_stack_frames_starting_from_caller_function=1, | ||
| ) | ||
|
|
||
| clicked_message_box_button = QtWidgets.QMessageBox.critical( | ||
| message_box_parent, | ||
| message_box_title, | ||
| message_box_content, | ||
| buttons=_get_buttons_for_message_box_type(message_box_type, is_cancellable=is_cancellable), | ||
| defaultButton=_get_default_button_for_message_box_type(message_box_type, is_cancellable=is_cancellable), | ||
| ) | ||
| return _check_whether_message_ok_was_clicked(message_box_type, clicked_message_box_button) | ||
| case _: | ||
| # Added guard to handle new message box types | ||
| assert_never(message_box_type) | ||
|
|
||
|
|
||
| def _get_buttons_for_message_box_type( | ||
| message_box_type: MessageBoxType, *, is_cancellable: bool | ||
| ) -> QtWidgets.QMessageBox.StandardButton: | ||
| if message_box_type == MessageBoxType.QUESTION: | ||
| return ( | ||
| (QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No) | ||
| if is_cancellable | ||
| else QtWidgets.QMessageBox.StandardButton.Yes | ||
| ) | ||
| return ( | ||
| (QtWidgets.QMessageBox.StandardButton.Ok | QtWidgets.QMessageBox.StandardButton.Cancel) | ||
| if is_cancellable | ||
| else QtWidgets.QMessageBox.StandardButton.Ok | ||
| ) | ||
|
|
||
|
|
||
| # Get the default button that will be pressed if the user presses ENTER in the open message box | ||
| def _get_default_button_for_message_box_type( | ||
| message_box_type: MessageBoxType, *, is_cancellable: bool | ||
| ) -> QtWidgets.QMessageBox.StandardButton: | ||
| if message_box_type == MessageBoxType.QUESTION: | ||
| return QtWidgets.QMessageBox.StandardButton.No if is_cancellable else QtWidgets.QMessageBox.StandardButton.Yes | ||
| return QtWidgets.QMessageBox.StandardButton.Cancel if is_cancellable else QtWidgets.QMessageBox.StandardButton.Ok | ||
|
|
||
|
|
||
| def _check_whether_message_ok_was_clicked( | ||
| message_box_type: MessageBoxType, | ||
| clicked_message_box_button: QtWidgets.QMessageBox.StandardButton | None, | ||
| ) -> bool: | ||
| # Pressing the ESC key in a QMessageBox can return None is no escape button can be determined or was configured (see https://doc.qt.io/qt-6/qmessagebox.html#default-and-escape-keys) | ||
| if message_box_type == MessageBoxType.QUESTION: | ||
| return ( | ||
| clicked_message_box_button is not None | ||
| and clicked_message_box_button == QtWidgets.QMessageBox.StandardButton.Yes | ||
| ) | ||
| return ( | ||
| clicked_message_box_button is not None and clicked_message_box_button == QtWidgets.QMessageBox.StandardButton.Ok | ||
| ) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.