kopia lustrzana https://github.com/corrscope/corrscope
[gui] When starting app, load config in GUI, not CLI (#149)
If loading invalid config via command line, show error via GUI dialog instead of CLI stacktrace/etc.pull/357/head
rodzic
80ec450dc9
commit
e058a6caa0
|
@ -115,9 +115,8 @@ def main(
|
||||||
|
|
||||||
show_gui = not any([write, play, render])
|
show_gui = not any([write, play, render])
|
||||||
|
|
||||||
# Create cfg: Config object.
|
# Gather data for cfg: Config object.
|
||||||
cfg: Optional[Config] = None
|
cfg_or_path: Union[Config, Path, None] = None
|
||||||
cfg_path: Optional[Path] = None
|
|
||||||
cfg_dir: Optional[str] = None
|
cfg_dir: Optional[str] = None
|
||||||
|
|
||||||
wav_list: List[Path] = []
|
wav_list: List[Path] = []
|
||||||
|
@ -144,8 +143,7 @@ def main(
|
||||||
if len(files) > 1:
|
if len(files) > 1:
|
||||||
raise click.ClickException(
|
raise click.ClickException(
|
||||||
f'Cannot supply multiple arguments when providing config {path}')
|
f'Cannot supply multiple arguments when providing config {path}')
|
||||||
cfg = yaml.load(path)
|
cfg_or_path = path
|
||||||
cfg_path = path
|
|
||||||
cfg_dir = str(path.parent)
|
cfg_dir = str(path.parent)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -159,11 +157,11 @@ def main(
|
||||||
f'Supplied nonexistent file or wildcard: {path}')
|
f'Supplied nonexistent file or wildcard: {path}')
|
||||||
wav_list += matches
|
wav_list += matches
|
||||||
|
|
||||||
if not cfg:
|
if not cfg_or_path:
|
||||||
# cfg and cfg_dir are always initialized together.
|
# cfg and cfg_dir are always initialized together.
|
||||||
channels = [ChannelConfig(str(wav_path)) for wav_path in wav_list]
|
channels = [ChannelConfig(str(wav_path)) for wav_path in wav_list]
|
||||||
|
|
||||||
cfg = default_config(
|
cfg_or_path = default_config(
|
||||||
master_audio=audio,
|
master_audio=audio,
|
||||||
# fps=default,
|
# fps=default,
|
||||||
channels=channels,
|
channels=channels,
|
||||||
|
@ -172,10 +170,11 @@ def main(
|
||||||
)
|
)
|
||||||
cfg_dir = '.'
|
cfg_dir = '.'
|
||||||
|
|
||||||
|
assert cfg_or_path is not None
|
||||||
if show_gui:
|
if show_gui:
|
||||||
def command():
|
def command():
|
||||||
from corrscope import gui
|
from corrscope import gui
|
||||||
return gui.gui_main(cfg, cfg_path)
|
return gui.gui_main(cfg_or_path)
|
||||||
|
|
||||||
if profile:
|
if profile:
|
||||||
import cProfile
|
import cProfile
|
||||||
|
@ -189,6 +188,16 @@ def main(
|
||||||
else:
|
else:
|
||||||
if not files:
|
if not files:
|
||||||
raise click.UsageError('Must specify files or folders to play')
|
raise click.UsageError('Must specify files or folders to play')
|
||||||
|
|
||||||
|
if isinstance(cfg_or_path, Config):
|
||||||
|
cfg = cfg_or_path
|
||||||
|
cfg_path = None
|
||||||
|
elif isinstance(cfg_or_path, Path):
|
||||||
|
cfg = yaml.load(cfg_or_path)
|
||||||
|
cfg_path = cfg_or_path
|
||||||
|
else:
|
||||||
|
assert False, cfg_or_path
|
||||||
|
|
||||||
if write:
|
if write:
|
||||||
write_path = get_path(audio, YAML_NAME)
|
write_path = get_path(audio, YAML_NAME)
|
||||||
yaml.dump(cfg, write_path)
|
yaml.dump(cfg, write_path)
|
||||||
|
|
|
@ -48,8 +48,7 @@ def res(file: str) -> str:
|
||||||
return str(APP_DIR / file)
|
return str(APP_DIR / file)
|
||||||
|
|
||||||
|
|
||||||
def gui_main(cfg: Config, cfg_path: Optional[Path]):
|
def gui_main(cfg_or_path: Union[Config, Path]):
|
||||||
# TODO read config within MainWindow, and show popup if loading fails.
|
|
||||||
# qw.QApplication.setStyle('fusion')
|
# qw.QApplication.setStyle('fusion')
|
||||||
QApp = qw.QApplication
|
QApp = qw.QApplication
|
||||||
QApp.setAttribute(qc.Qt.AA_EnableHighDpiScaling)
|
QApp.setAttribute(qc.Qt.AA_EnableHighDpiScaling)
|
||||||
|
@ -63,7 +62,7 @@ def gui_main(cfg: Config, cfg_path: Optional[Path]):
|
||||||
QApp.setFont(font)
|
QApp.setFont(font)
|
||||||
|
|
||||||
app = qw.QApplication(sys.argv)
|
app = qw.QApplication(sys.argv)
|
||||||
window = MainWindow(cfg, cfg_path)
|
window = MainWindow(cfg_or_path)
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,14 +71,15 @@ class MainWindow(qw.QMainWindow):
|
||||||
Main window.
|
Main window.
|
||||||
|
|
||||||
Control flow:
|
Control flow:
|
||||||
__init__
|
__init__: either
|
||||||
load_cfg
|
- load_cfg
|
||||||
|
- load_cfg_from_path
|
||||||
|
|
||||||
# Opening a document
|
Opening a document:
|
||||||
load_cfg
|
- load_cfg_from_path
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, cfg: Config, cfg_path: Optional[Path]):
|
def __init__(self, cfg_or_path: Union[Config, Path]):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
# Load UI.
|
# Load UI.
|
||||||
|
@ -109,7 +109,14 @@ class MainWindow(qw.QMainWindow):
|
||||||
self.corr_thread: Optional[CorrThread] = None
|
self.corr_thread: Optional[CorrThread] = None
|
||||||
|
|
||||||
# Bind config to UI.
|
# Bind config to UI.
|
||||||
self.load_cfg(cfg, cfg_path)
|
if isinstance(cfg_or_path, Config):
|
||||||
|
self.load_cfg(cfg_or_path, None)
|
||||||
|
elif isinstance(cfg_or_path, Path):
|
||||||
|
self.load_cfg_from_path(cfg_or_path)
|
||||||
|
else:
|
||||||
|
raise TypeError(
|
||||||
|
f"argument cfg={cfg_or_path} has invalid type {obj_name(cfg_or_path)}"
|
||||||
|
)
|
||||||
|
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
|
@ -133,37 +140,6 @@ class MainWindow(qw.QMainWindow):
|
||||||
channel_view: "ChannelTableView"
|
channel_view: "ChannelTableView"
|
||||||
channelsGroup: qw.QGroupBox
|
channelsGroup: qw.QGroupBox
|
||||||
|
|
||||||
def closeEvent(self, event: QCloseEvent) -> None:
|
|
||||||
"""Called on closing window."""
|
|
||||||
if self.prompt_save():
|
|
||||||
event.accept()
|
|
||||||
else:
|
|
||||||
event.ignore()
|
|
||||||
|
|
||||||
def on_action_new(self):
|
|
||||||
if not self.prompt_save():
|
|
||||||
return
|
|
||||||
cfg = default_config()
|
|
||||||
self.load_cfg(cfg, None)
|
|
||||||
|
|
||||||
def on_action_open(self):
|
|
||||||
if not self.prompt_save():
|
|
||||||
return
|
|
||||||
name, file_type = qw.QFileDialog.getOpenFileName(
|
|
||||||
self, "Open config", self.cfg_dir, "YAML files (*.yaml)"
|
|
||||||
)
|
|
||||||
if name != "":
|
|
||||||
cfg_path = Path(name)
|
|
||||||
try:
|
|
||||||
# Raises YAML structural exceptions
|
|
||||||
cfg = yaml.load(cfg_path)
|
|
||||||
# Raises color getter exceptions
|
|
||||||
# ISSUE: catching an exception will leave UI in undefined state?
|
|
||||||
self.load_cfg(cfg, cfg_path)
|
|
||||||
except Exception as e:
|
|
||||||
qw.QMessageBox.critical(self, "Error loading file", str(e))
|
|
||||||
return
|
|
||||||
|
|
||||||
def prompt_save(self) -> bool:
|
def prompt_save(self) -> bool:
|
||||||
"""
|
"""
|
||||||
Called when user is closing document
|
Called when user is closing document
|
||||||
|
@ -188,6 +164,45 @@ class MainWindow(qw.QMainWindow):
|
||||||
else:
|
else:
|
||||||
return self.on_action_save()
|
return self.on_action_save()
|
||||||
|
|
||||||
|
def closeEvent(self, event: QCloseEvent) -> None:
|
||||||
|
"""Called on closing window."""
|
||||||
|
if self.prompt_save():
|
||||||
|
event.accept()
|
||||||
|
else:
|
||||||
|
event.ignore()
|
||||||
|
|
||||||
|
def on_action_new(self):
|
||||||
|
if not self.prompt_save():
|
||||||
|
return
|
||||||
|
cfg = default_config()
|
||||||
|
self.load_cfg(cfg, None)
|
||||||
|
|
||||||
|
def on_action_open(self):
|
||||||
|
if not self.prompt_save():
|
||||||
|
return
|
||||||
|
name, file_type = qw.QFileDialog.getOpenFileName(
|
||||||
|
self, "Open config", self.cfg_dir, "YAML files (*.yaml)"
|
||||||
|
)
|
||||||
|
if name != "":
|
||||||
|
cfg_path = Path(name)
|
||||||
|
self.load_cfg_from_path(cfg_path)
|
||||||
|
|
||||||
|
def load_cfg_from_path(self, cfg_path: Path):
|
||||||
|
# Bind GUI to dummy config, in case loading cfg_path raises Exception.
|
||||||
|
if self.model is None:
|
||||||
|
self.load_cfg(default_config(), None)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Raises YAML structural exceptions
|
||||||
|
cfg = yaml.load(cfg_path)
|
||||||
|
|
||||||
|
# Raises color getter exceptions
|
||||||
|
self.load_cfg(cfg, cfg_path)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
qw.QMessageBox.critical(self, "Error loading file", str(e))
|
||||||
|
return
|
||||||
|
|
||||||
def load_cfg(self, cfg: Config, cfg_path: Optional[Path]):
|
def load_cfg(self, cfg: Config, cfg_path: Optional[Path]):
|
||||||
self._cfg_path = cfg_path
|
self._cfg_path = cfg_path
|
||||||
self._any_unsaved = False
|
self._any_unsaved = False
|
||||||
|
|
Ładowanie…
Reference in New Issue