Skip to content

Draft: Reimplement halshow in Python#4231

Open
petterreinholdtsen wants to merge 4 commits into
LinuxCNC:masterfrom
petterreinholdtsen:reimplement-halshow-python
Open

Draft: Reimplement halshow in Python#4231
petterreinholdtsen wants to merge 4 commits into
LinuxCNC:masterfrom
petterreinholdtsen:reimplement-halshow-python

Conversation

@petterreinholdtsen

Copy link
Copy Markdown
Collaborator

Replace the tcl/tk implementation of halshow with a Python/Qt implementation, and add new graph support using graphviz to show the interconnection in HAL between pins and signals.

Replace the Tcl/Tk halshow (tcl/bin/halshow.tcl) with a Python/Qt
implementation using qtpy for cross-backend compatibility. The new
edition provides identical functionality plus additional features:

Core architecture:
- Direct shared memory access via _hal C extension, eliminating
  subprocess overhead. Creates a minimal component "_halshow_{pid}"
  that is cleanly removed on exit (ready() -> exit()) to prevent
  zombie accumulation.
- Added get_info_components(), get_info_functions(),
  get_info_threads() to halmodule.cc for SHM-based listing of
  components/functions/threads without halcmd subprocess calls.
- Robust cleanup: atexit handler + signal handlers (SIGINT/SIGTERM/SIGHUP)
  ensure component is removed from SHM on any exit path. Fixed a bug where
  the old Tcl edition leaked components when exiting via SIGPIPE or
  "linuxcnc -l" (which raises SystemExit).

Watch tab:
- Value|Name|Buttons layout matching Tcl halshow order
- Full pin names shown in watch rows (not truncated)
- [Tgl]/[Set]/[Clr] buttons for writable bit signals, plain value for read-only
- Buttons dynamically disabled when signal gains writers at runtime
- Halcmd fallback for writer detection on old _hal.so lacking WRITERS field

Show tab:
- Signal detail matches halcmd "show sig" monospace table format exactly
- Value right-aligned in 5-char field, matching Tcl edition
- Tree view uses monospace font with no word wrap

Main window layout:
- Tree view and tabs side-by-side in a splitter
- Command entry and status bar span full width below the splitter (Tcl match)
- All user-facing GUI text translatable via PO files / gettext (_() wrappers)

This patch was created with help from OpenCode using local llama.cpp
server with Qwen 3.6.
…zation

Add a new GRAPH tab (between WATCH and SETTINGS) that renders HAL topology as
a bipartite graph (component → signal → component), laid out by Graphviz dot.

Graph data model:
- GraphDataBuilder collects pins/signals from SHM into structured component/signal dicts,
  with O(1) pin-to-component index for fast edge resolution
- Three-tier fallback for resolving signal connections: pure-SHM pin SIGNAL field,
  _hal.get_signal_connections(), or halcmd show sig via background QThread
- Owner detection falls back to heuristics when old _hal.so lacks OWNER field

Layout engine (GraphLayout.compute):
- Builds directed AGraph with component boxes and diamond-shaped signal nodes
- Runs dot for crossing-minimized placement; extracts edge splines for rendering
- Coordinates scaled from points (72 dpi) to device pixels (96 dpi)

Rendering (QGraphicsView scene):
- ComponentItem: rounded rectangles with blue header, green IN pins (left column),
  red OUT pins (right column), and connection markers on edges
- SignalNodeItem: orange diamonds sized to fit signal names
- Edges route from writer pin → signal diamond perimeter → reader pin marker,
  each segment with arrowhead; uses dot splines when available, cubic bezier fallback
- Multi-edge spreading between same component pair

Interaction:
- Pan via middle/left mouse drag; zoom via scroll wheel or +/- buttons
- Right-click context menus on components (add pins to watch) and edges (watch signal)
- "Hide unused pins" toggle filters component boxes to only connected pins
- Lazy layout computation deferred until first tab activation

CLI --dotty flag:
- Print HAL topology as DOT source to stdout then exit, with layout parameters
  matching the GRAPH tab for debugging purposes

This patch was created with help from OpenCode using local llama.cpp
server with Qwen 3.6.
@petterreinholdtsen petterreinholdtsen changed the title Draft: Reimplement halshow python Draft: Reimplement halshow in Python Jul 9, 2026
@grandixximo

grandixximo commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

You might want to enable the executable bit in git for halshow.py
I did quick testing, not looked at the graph yet, should pygraphviz become a dependency?
The grouped view of pins and parameters is the new default, but seems not working in the port?

@petterreinholdtsen

petterreinholdtsen commented Jul 10, 2026 via email

Copy link
Copy Markdown
Collaborator Author

@grandixximo

Copy link
Copy Markdown
Contributor

What is this? I do not believe I have used or seen this myself.
Something from after 2.9?

Yes, just made it in 2.10 a few weeks back, see #4147

In PyQt6 and PySide6, WindowStaysOnTop moved from Qt to
Qt.WindowType. Add a compatibility shim that resolves the flag for
both backend families.

Fixes crash when applying settings (alwaysOnTop toggle) in halshow.py.

This patch was created with help from OpenCode using local llama.cpp
server with Qwen 3.6.
@petterreinholdtsen

petterreinholdtsen commented Jul 10, 2026 via email

Copy link
Copy Markdown
Collaborator Author

Comment thread scripts/halshow.py Outdated
@hansu

hansu commented Jul 12, 2026

Copy link
Copy Markdown
Member

Nice! It needs some fine tuning, but most of the features of the current halshow I can find 👍

Some notes:

  • In the SHOW tab, it should list the pins,... when clicking on the node, e.g. clicking ob "Pins" should list all pins, clicking "axis" should list all pins axis.*

  • Clicking on a slection in the SHOW tab crashes the application with

    File "/home/cnc/linuxcnc-master/scripts/halshow.py", line 3390, in _show_context_menu
        selected_text = self.show_browser.selectedText().strip()
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    AttributeError: 'QTextBrowser' object has no attribute 'selectedText'
    
  • I think it looks better if the bubbles for bool values are right aligned

  • The expand/collapse button for the tree view is missing

  • Very good idea to integrate the graphviz graph. But it's very hard to see the small boxes. Maybe you can get some inspiration from: https://github.com/multigcs/halviewer (or just integrate that one)

@petterreinholdtsen

petterreinholdtsen commented Jul 13, 2026 via email

Copy link
Copy Markdown
Collaborator Author

@petterreinholdtsen petterreinholdtsen force-pushed the reimplement-halshow-python branch from 2a433c3 to 78c82ae Compare July 13, 2026 07:13
@Sigma1912

Copy link
Copy Markdown
Contributor

There seems to be an issue with some of the value conversions (eg joint.N.pos-cmd):

hal_show_py

@hansu

hansu commented Jul 13, 2026

Copy link
Copy Markdown
Member

[Hans Unzner]
Two more need fixing ;-)
Fixing. How do you trigger these errors? My tests using Python 3.13.5 do not show these problems.

Python 3.11.2 on Bookworm

Clicking on a slection in the SHOW tab crashes the application with

Sorry I was talking about right-click:

halshow-crash.mp4

@hansu

hansu commented Jul 13, 2026

Copy link
Copy Markdown
Member

There seems to be an issue with some of the value conversions (eg joint.N.pos-cmd):

What value did you expect (does halshow show)?

@Sigma1912

Copy link
Copy Markdown
Contributor

What value did you expect (does halshow show)?

Well, it shows a float, like 5.325

@hansu

hansu commented Jul 14, 2026

Copy link
Copy Markdown
Member

What value did you expect (does halshow show)?

Well, it shows a float, like 5.325

I get a float display. Probably the value is too large to fit into the column width, so the end is cut.
And I see the setting for the values' column width is gone. @petterreinholdtsen please add.

@Sigma1912

Copy link
Copy Markdown
Contributor

Probably the value is too large to fit into the column width, so the end is cut.

Yes, seems to be missing formatting.

As hansu already mentioned, the graph takes a lot of panning and zooming so having the mouse scroll wheel not supported for zooming is real pain. To make the graph more compact I would drop the extra nodes for the signal names and show those when selecting the line.

IMO the biggest problem with these hal graphs is that they very quickly become too large and unwieldy.

@Sigma1912

Copy link
Copy Markdown
Contributor

Just as an example, this is a config from my test setup with a relatively small hal file (my actual machines have hal setups with >600 lines). This config has spindle orientation and this is where a graphical representation would be really useful. As it is the 'Graph' tab just gives me everything and I have to zoo, pan and scroll to find the relevant components and then drag along trying to follow signals back and forth:

Screenshot from 2026-07-15 11-46-32

The problem is that I'm given too much information to actually be helpful. What would be much more useful is a graph of the components I select from the tree. After all the 'Show' and 'Watch' tabs don't just list every possible piece of information there is either and it would be very bad if they did.

@grandixximo

Copy link
Copy Markdown
Contributor

A decent solution I found on a similar tool I experimented with, was filtering by the relevant pin to visualize, plus a selection for connections branching, that should filter everything connected to what you are wanting to see without including everything that's not relevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants