Jump to content

.py communication with .qml for printer status plugin


Recommended Posts

Posted · .py communication with .qml for printer status plugin

Dear Cura plugin community,


I would like to build an addon, with which I can display the printer's status and printbed temp within the "Monitor"-Tab.

So far, I can query my printer via Wifi and get a json-style response via QNetworkRequest. However, since I am unfamiliar with Qt and QML, I am having troubles parsing this data to a Label within MonitorMain.qml


So far, I have:



class MonitorStage(CuraStage):


   def Response(self, reply):
    response  = json.loads#Here I get the json from the printer

I'm having a hard time with Qt's signal/slot system, where I'm struggling to parse a value from the response to a QLabel in MonitorMain.qml



Would any of the more seasoned programmers on this board be able to point me to the right directions?


Best regards,



  • Link to post
    Share on other sites

    Posted · .py communication with .qml for printer status plugin

    Well, you shouldn't add it in the monitor stage directly, that's for one. The monitor stage is intended to display data that it gets from 
    a "PrinterOutputDevice" (or in your case, probably the "NetworkedPrinterOutputDevice")
    As you may know, Cura has a pretty extensive plugin system. Both situations that also do what you want are the "UM3NetworkPrinting" plugin (bundled with cura) and the OctoprintPlugin (https://github.com/fieldOfView/Cura-OctoPrintPlugin).

    So what needs to be done is that you create your own version of the printerOutputDevice / NetworkedPrinterOutputDevice (by means of inheritance) and ensure that the properties / functions that it exposes are filled with the correct data.

    A bit more general info on Qt/QML to make the code a bit more understandable; Qt heavily relies on properties (pyqtProperty), signals (pyqtSignal) and slots (pyqtSlot). Properties are essentially attributes, but with one major exception; they have the "notify" ability. When you use a property in QML and the property is changed on the python side, you can notify the QML that this happend by emitting the right signal (signalling the change, hence the name).  Lets look at a bit of code:

    @pyqtProperty("QVariantList", notify=printJobsChanged)
    def printJobs(self) -> List[UM3PrintJobOutputModel]:
      return self._print_jobs

    First of is the bit that starts with the @ sign. This is a decorator, which is a pretty nifty built in feature of python. What it essentially does is taking whatever is below it and modify it (eg "decorating it"). In this case, it's turning the function into a property that is also exposed to QML. The first parameter is the return type (A list of QVariant) and the second one is telling it what signal is emitted if the value is changed. You can either set the "notify" or you can set "constant=True" in which case you indicate that the value will never change once set.

    Slots on the other hand are what Qt calls exposed functions. So all functions that are decorated with the pyqtSlot are functions that can be called from QML. They use a similar pattern as the properties.

    @pyqtSlot(QObject, name="setActivePrinter")
    def setActivePrinter(self, printer: Optional[PrinterOutputModel]) -> None:
      if self.activePrinter == printer:
      self._active_printer = printer

    The first parameter of the decoration is the first parameter accepted by the function (so the printer parameter). The name is set as this is usefull for debugging. Finally, you could also set the "result" parameter, which indicates the return type of the slot (if any).

    • Like 2
    Link to post
    Share on other sites

    Posted · .py communication with .qml for printer status plugin

    Dear Nallath,


    Thank you do much for this thorough answer. I certainly wasn't expecting this amount of detail.


    I have been looking into ahoeben's (fileofview) Octoprintplugin, especialy how he accesses the PrintMonitor part.
    However, since I'm unfamiliar with the inner workings of Cura, it raised a lot more questions, which is why I reverted to not "reusing" Cura's internal features, but just redrawing GUI elements in the MonitorStage and feeding it with values.

    Needless to say, that's apparently not the way to go 🙂


    @nallath, thank you so much again for clarifying this situation! I will a take a more in-depth dive into Cura's code and figure out how

    all the componenets work together.

    Is there by any chance a graphic/description that details how Cura's set up internally, that I missed?


    Al the best,


  • Link to post
    Share on other sites

    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now
    • Our picks

      • Introducing the UltiMaker Factor 4
        We are happy to announce the next evolution in the UltiMaker 3D printer lineup: the UltiMaker Factor 4 industrial-grade 3D printer, designed to take manufacturing to new levels of efficiency and reliability. Factor 4 is an end-to-end 3D printing solution for light industrial applications
          • Like
        • 3 replies
      • UltiMaker Cura 5.7 stable released
        Cura 5.7 is here and it brings a handy new workflow improvement when using Thingiverse and Cura together, as well as additional capabilities for Method series printers, and a powerful way of sharing print settings using new printer-agnostic project files! Read on to find out about all of these improvements and more. 
        • 26 replies
    • Create New...