Add install headless extension and call it by Rylern · Pull Request #2027 · qupath/qupath

@Rylern

A proposal to fix #2007. This is done by:

  • Adding a installHeadless() function to QuPathExtension with a default (do-nothing) implementation.
  • Calling installHeadless() of all current extensions when the script command is used when running QuPath from the command line.

@Rylern

@Rylern Rylern deleted the headless-extensions branch

November 11, 2025 09:46

@NicoKiaru

Hello @Rylern,

Is installHeadless called even when QuPath is launched with a GUI ?
It looks like no. Is it the intended behaviour ? Because then the code is a bit weird since I have to put in two places the method to add the custom image servers ser/deserializers.

    @Override
    public void installExtension(QuPathGUI qupath) {
    	if (alreadyInstalled || !checkCompatibility())
			return;
		
		try {
            addWarpyImageServer();
			// Add ImageCombinerWarpy action
			var imageCombinerWarpy = ActionTools.createAction(new InteractiveImageCombinerWarpyCommand(qupath), "Interactive image combiner Warpy");
			MenuTools.addMenuItems(qupath.getMenu("Analyze", false), imageCombinerWarpy);
	    	alreadyInstalled = true;
		} catch (Throwable t) {
			logger.debug("Unable to add ImageCombinerWarpy to menu", t);
		}		
    }

    @Override
    public void installHeadless() {
        addWarpyImageServer();
    }

@Rylern

Is installHeadless called even when QuPath is launched with a GUI ?

No, this is mentioned in the function documentation:

* Install the extension in headless mode. This function is only called if QuPath is run without the user
* interface.
* <p>
* See {@link #installExtension(QuPathGUI)} for installing the extension when the graphical user interface
* is used.

This allows for more flexibility, as it means you can have some code that runs when the GUI is not present, but not when the GUI is present.