One of the most asked questions on the mailing list is about how to customize this or that part of the GUI. There isn't really a standard answer for this, hence this blog post with a concrete example.
Camelot comes with lots of predefined GUI elements which are easily bound to your data model. This has the advantage of getting your project up and running in no time. But once you want to start customizing the GUI beyond what Camelot provides out-of-the-box, you need to switch gears.
Suddenly, you need to know all about SQLAlchemy, Qt, PyQt/PySide and the internals of Camelot. There is no way around this, but this post aims to be a gentle introduction.
In this post, we'll change the movie store example, to show a chart in the table view when a row is clicked, instead of opening a form.
The first thing you need to know is that most customizations of the GUI can be done through the Actions
framework. The Actions framework is some kind of mini-framework inside Camelot. Every time the user clicks a button in a Camelot application to do something, an Action is triggered, and those Actions can be customized.Make sure to read the Actions Tutorial
to get a good idea of how actions work and how to write them.In this case
, when the user clicks on a row in the table, we want a chart to show up beneath the list, instead of a form that opens. We'll intercept the default action that opens the form and put our own action in place :
Programming with multiple threads sounds scary. However multiple threads or processes are essential to keep an application responsive to a user. Camelot runs two threads
, one for accessing the GUI, and one for accessing the data model. So as a developer, you should always keep those two things clearly separated. Doing so will ensure that your application remains responsive. Whenever you write an action, you should ask yourself if the action starts with doing something in the model, or does it start with doing something in the GUI.Actions that start in the model should overwrite the model_run method. In this case, the first thing we want to do is to strip all the data for the chart from the model.
We'll assume for a moment you are aware how the Matplotlib integration
in Camelot works. The model_run
method receives the model_context
argument. The model context provides access to those parts of the model that are active when the action was triggered. We use the model context to get to the movie object thatwas selected, and then create the chart. Once the chart is made, we yield an ActionStep, in this case UpdateChart to display the chart in the GUI.
Yielding the action step will pass control to the GUI.
Of course the UpdateChart action step does not exist yet, so we'll have to create that one as well :
In the gui_run
method, we receive the gui_context
object. The gui context provides access to the the relevant widgets we need. One of the fine things of Qt is that every widget can have a name and you can find a widget with a certain name inside a widget tree with the findChild
method. This can be handy to look for Camelot widgets (most widgets in Camelot have a name, to find out which one, look at the source code) or your own widgets, and manipulate them accordingly.Both Qt and Camelot have a set of editors, here we'll reuse the ChartEditor from Camelot to display the chart. So we create a chart_editor, and add it to the layout of the table view.
Wow, glad you made it. I hope this article can convince you that investing some time in PyQt/PySide can help a lot when you need to customize Camelot beyond what it provides out of the box. The users of your application will certainly appreciate it. For questions, please consider the mailing list
In October and November, we're organizing a set of SQLAlchemy
courses that provide you with the necessary skills and backround information to enjoy developing these kind of applications.