Turning my 3D-Printer into a Laser Engraver 3: GUI

This post briefly discusses my choices regarding language and frameworks for building the Slicer GUI. It contains little technical information.

My first instinct in building the application was to use Qt with C++. I’ve used this a little bit before and always found it quite pleasant. This idea was thrown into the wind when I realized that Python, which I currently use for almost everything, had Qt bindings too. So after a short time trying to evaluate the difference between PySide and PyQt (some differences in licensing, PySide is the official binding while PyQt has more active, community-driven development; apparently the API is near identical), I settled on PyQt.

Installing it was pure pleasure, especially recalling the troubles I had when I first installed QtCreator about two years ago. I started a new project with a new virtual environment in PyCharm, put import PyQt5 into a file, and told PyCharm to sort out missing imports. Not five minutes after this, I had my main window.

Now, I’m pretty good with Python, but only have a passing familiarity with Qt. This meant lots of googling for very basic things, which was largely a very pleasant experience. Everything is just so simple. You want a button to open a native file picker dialog, filtered by image type?

open_source_image_button = QPushButton( 'Open Image', sidebar_widget )
open_source_image_button.clicked.connect( self.open_source_file )
sidebar_layout.addWidget( open_source_image_button )

def open_source_file( self ):
    file_name, file_type = QFileDialog.getOpenFileName( self, 'Open file', filter="All Graphics (*.png *.bmp *.jpeg *.jpg *.svg);;Pixel Graphics (*.png *.bmp *.jpeg *.jpg);;Vector Graphics (*.svg)" )

    if file_name:
        open( file_name, 'r' ) as file:
            # ...

Couldn’t be easier. One thing that did kind of bother me was that I couldn’t find a clear explanation of how exactly I’m supposed to use the layout system. I create widgets, but then to nest widgets, I create layouts from the widgets and put the nested widgets into the layout, not the widget? It works well enough for now, but I can’t quite shake the feeling that I might be doing it wrong by accident. This is exactly how it is supposed to be done and is perfectly sensible, given that you want to control how child widgets are laid out.

Three hundred tabs and fifty google searches later I had the following:

  • The realization that there exists essentially no documentation for PyQt5
  • The realization that this doesn’t matter, as the documentation for C++ is outstanding and can be used instead. In all my (admittedly very restricted) use cases so far, the function calls can be copied nearly verbatim.
  • This beautiful atrocity:

The Open Image button allows you to load images (Qt even handles vector graphics without any action on my part!), which are then displayed. Process Settings opens the Slicer Settings window, which currently contains absolutely nothing, but will eventually hold all relevant parameters for generating the code. Save GCode allows you to select a location and file name to export the gcode file to. The file is not actually created, as the program has no understanding of what gcode is, currently. This is what I will tackle next.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.