riverarchitect.gui
Graphical interface for River Architect.
Two front ends ship with the package and main() picks between them:
Qt (riverarchitect.gui.qt) is the default. It renders with the platform’s native
widgets, so the window looks like the rest of the desktop on Linux, Windows and macOS, and
it scales correctly on HiDPI screens. It runs on PySide6 or on the PyQt5 that QGIS brings.
tkinter (riverarchitect.gui.main) is the fallback, used when no Qt binding is
installed. It needs nothing beyond the standard library, so the interface always opens.
Start it with the riverarchitect console script, with python -m riverarchitect, or:
from riverarchitect.gui import main
main()
Set RIVERARCHITECT_GUI to qt or tk to force a front end, which is mostly useful
for testing or when a Qt install is misbehaving.
- riverarchitect.gui.main(argv=None)
Console-script entry point. Starts the graphical interface.
A single positional argument sets the project directory.
- Returns:
process exit status.
- Return type:
- riverarchitect.gui.available_backends()[source]
Return the front ends that can run here, best first.
- Returns:
some of
"qt"and"tk"; empty if neither toolkit is importable.- Return type:
- riverarchitect.gui.select_backend(preferred=None)[source]
Choose a front end.
Qt front end
Qt front end for River Architect.
The default interface. Runs on PySide6, or on the PyQt5 that comes with QGIS - see
riverarchitect.gui.qt.qtcompat for why both are supported. When neither binding is
installed, QT_AVAILABLE is False and
riverarchitect.gui falls back to the tkinter interface.
Qt binding shim: run on PySide6, or on the PyQt5 that ships with QGIS.
River Architect is used from two different interpreters. Analysis runs in a conda environment, where PySide6 installs cleanly from PyPI or conda-forge. Mapping has to run in whichever interpreter owns the QGIS bindings, and QGIS brings its own PyQt5 - installing a second Qt into that interpreter is how you get two Qt libraries in one process and a segfault. So the interface targets whatever Qt is already there:
PySide6, if it is importable, and
PyQt5 otherwise, which is what a QGIS-enabled interpreter has.
Only the handful of names the interface actually uses are re-exported, and only in the
fully-qualified enum form (Qt.AlignmentFlag.AlignLeft, not Qt.AlignLeft), which is
the spelling both bindings accept.
QT_BINDING names the binding in use; QT_AVAILABLE is False when neither is
installed, which is what makes the tkinter fallback kick in.
- riverarchitect.gui.qt.qtcompat.exec_app(app)[source]
Start the event loop.
exec_()on PyQt5,exec()on PySide6.
- riverarchitect.gui.qt.qtcompat.exec_dialog(dialog)[source]
Show a modal dialog and return its result code.
Shared behaviour for Qt module tabs.
The tkinter base class (riverarchitect.gui.base) owns its own menu bar and resizes
the whole window whenever its tab is selected. Neither is right in a Qt application: menus
belong to the main window, and a tab must not move the window under the user. What is left
here is what a tab genuinely shares - the unit system, the condition list, and a way to run
work off the interface thread.
- class riverarchitect.gui.qt.base.RaTab(*args, **kwargs)[source]
Bases:
QWidgetBase class for a module tab.
Subclasses set
titleandsubtitle, then build their widgets intobody. Long-running work goes throughrun_in_background(), which keeps the interface responsive and marshals the result back onto the Qt thread.- title = 'River Architect'
Tab label.
- subtitle = ''
One or two lines shown under the tab heading.
- run_in_background(work, on_success, on_error)[source]
Run
work()on a worker thread and deliver the outcome on the Qt thread.Qt widgets may only be touched from the thread that created them, so the worker emits a signal instead of calling back directly. A queued signal connection is the Qt equivalent of tkinter’s
widget.after(0, ...).
- set_unit(unit)[source]
Switch the unit system and notify the subclass through
on_unit_change().
Qt main window: a tabbed shell with one tab per module.
Structurally the same as the tkinter window it replaces, with the differences a real toolkit makes possible: the menu bar belongs to the window rather than being rebuilt on every tab change, the status bar reports the project directory, and a tab that fails to construct is replaced by a message instead of taking the window down.
- class riverarchitect.gui.qt.main.RiverArchitectWindow(*args, **kwargs)[source]
Bases:
QMainWindowTop-level window holding one tab per module.
- select_tab(group, tab=None)[source]
Bring a module tab to the front. Used by the Live Guide.
- Parameters:
group (str) – the top-level tab, as
TAB_GROUPSnames it.tab (str) – the module tab within it. Defaults to the group itself.
- Returns:
True when the tab was found and selected.
- Return type:
- riverarchitect.gui.qt.main.run(argv=None)[source]
Create the application, show the window and run the event loop.
- riverarchitect.gui.qt.main.TAB_GROUPS = (('Get Started', (<class 'riverarchitect.gui.qt.getstarted_tab.GetStartedTab'>,)), ('Lifespan', (<class 'riverarchitect.gui.qt.lifespan_tab.LifespanTab'>, <class 'riverarchitect.gui.qt.maxlifespan_tab.MaxLifespanTab'>)), ('Morphology', (<class 'riverarchitect.gui.qt.terraforming_tab.TerraformingTab'>, <class 'riverarchitect.gui.qt.riverbuilder_tab.RiverBuilderTab'>, <class 'riverarchitect.gui.qt.volume_tab.VolumeTab'>)), ('Ecohydraulics', (<class 'riverarchitect.gui.qt.sharc_tab.SharcTab'>, <class 'riverarchitect.gui.qt.stranding_tab.StrandingTab'>, <class 'riverarchitect.gui.qt.recruitment_tab.RecruitmentTab'>)), ('Project Maker', (<class 'riverarchitect.gui.qt.projectmaker_tab.ProjectMakerTab'>,)), ('Maps', (<class 'riverarchitect.gui.qt.mapping_tab.MappingTab'>,)))
Top-level tabs and their sub-tabs, reproducing the grouping of the ArcGIS version: a module either stands alone or sits inside a themed group.
Nonemeans the entry is a single tab rather than a group.
- riverarchitect.gui.qt.main.TABS = (<class 'riverarchitect.gui.qt.getstarted_tab.GetStartedTab'>, <class 'riverarchitect.gui.qt.lifespan_tab.LifespanTab'>, <class 'riverarchitect.gui.qt.maxlifespan_tab.MaxLifespanTab'>, <class 'riverarchitect.gui.qt.terraforming_tab.TerraformingTab'>, <class 'riverarchitect.gui.qt.riverbuilder_tab.RiverBuilderTab'>, <class 'riverarchitect.gui.qt.volume_tab.VolumeTab'>, <class 'riverarchitect.gui.qt.sharc_tab.SharcTab'>, <class 'riverarchitect.gui.qt.stranding_tab.StrandingTab'>, <class 'riverarchitect.gui.qt.recruitment_tab.RecruitmentTab'>, <class 'riverarchitect.gui.qt.projectmaker_tab.ProjectMakerTab'>, <class 'riverarchitect.gui.qt.mapping_tab.MappingTab'>)
Flat list of every module tab, in the order they appear.
tkinter fallback
Shared tkinter base class for River Architect module tabs.
This is the fallback interface, used when no Qt binding is installed; see
riverarchitect.gui for how the two front ends are chosen and
riverarchitect.gui.qt for the default one.
Carries over the structure of the original child_gui.RaModuleGui: every module tab is a
tk.Frame subclass with a unit-system toggle and a condition list. What changed is that
the base class no longer reaches into arcpy or into workbook templates to build itself, so a
tab can be constructed and tested without any geoprocessing stack - and that the window
owns the menu bar. The original rebuilt the whole menu bar, and resized and re-centred the
window, on every tab change; menus are now built once by
riverarchitect.gui.main.RiverArchitectGui.
- class riverarchitect.gui.base.RaModuleGui(master=None)[source]
Bases:
FrameBase class for a module tab.
Subclasses set
titleand build their widgets in__init__.- Parameters:
master – parent widget, normally the notebook tab container.
- title = 'River Architect'
Tab title.
- set_unit(unit)[source]
Switch the unit system and notify the subclass through
on_unit_change().
- refresh_conditions(listbox=None, scrollbar=None)[source]
Reload the list of available conditions from the project directory.
Main tkinter window: a notebook of module tabs.
The fallback interface, used when no Qt binding is installed. See riverarchitect.gui
for the backend choice and riverarchitect.gui.qt for the default front end.
Carries over the structure of the original parent_gui.RaGui, with three deliberate
differences:
selecting a tab no longer calls
os.chdir(). The original changed the process working directory per tab, which coupled unrelated modules through global state and made behaviour depend on click order. Paths are now explicit;the window owns the menu bar and builds it once. The original rebuilt every menu on each tab change, which leaked a
tk.Menuper click;selecting a tab no longer resizes and re-centres the window, which fought whatever size the user had chosen.
- class riverarchitect.gui.main.RiverArchitectGui(master=None)[source]
Bases:
FrameTop-level window holding one tab per module.
- select_tab(group, tab=None)[source]
Bring a module tab to the front. Used by the Live Guide.
- Parameters:
group (str) – the top-level tab, as
TAB_GROUPSnames it.tab (str) – the module tab within it. Defaults to the group itself.
- Returns:
True when the tab was found and selected.
- Return type:
- riverarchitect.gui.main.main(argv=None)[source]
Start the tkinter interface.
Normally reached through
riverarchitect.gui.main(), which picks a front end.
- riverarchitect.gui.main.TAB_GROUPS = (('Get Started', (<class 'riverarchitect.gui.getstarted_tab.GetStartedGui'>,)), ('Lifespan', (<class 'riverarchitect.gui.lifespan_tab.LifespanGui'>, <class 'riverarchitect.gui.maxlifespan_tab.MaxLifespanGui'>)), ('Morphology', (<class 'riverarchitect.gui.terraforming_tab.TerraformingGui'>, <class 'riverarchitect.gui.riverbuilder_tab.RiverBuilderGui'>, <class 'riverarchitect.gui.volume_tab.VolumeGui'>)), ('Ecohydraulics', (<class 'riverarchitect.gui.sharc_tab.SharcGui'>, <class 'riverarchitect.gui.stranding_tab.StrandingGui'>, <class 'riverarchitect.gui.recruitment_tab.RecruitmentGui'>)), ('Project Maker', (<class 'riverarchitect.gui.projectmaker_tab.ProjectMakerGui'>,)), ('Maps', (<class 'riverarchitect.gui.mapping_tab.MappingGui'>,)))
Top-level tabs and their sub-tabs, matching the Qt front end and the ArcGIS version.