Python Qt Designer using PyQt5 Library
Table of Contents
Used software:
The programming language used to implement the script editor is Python using the Qt framework. The Python Qt Framework is a class library based on C++ for cross-platform programming of graphical user interfaces, so-called GUIs.
To implement the Visual Programming Tool, the Python Qt Designer supplied with PyQt5 is first used to create a graphical user interface. This tool can be used to create a graphical user interface without any program logic. The creation of the graphical user interface for the Visual Programming Tool is explained in detail later. I have already used the PyQt5 for the GUI designing and I did for the Raspberry Pi. You care read my article “Raspberry Pi Industrial Automation HMI/GUI designing using PYQT5”.
The graphical user interface must be compiled for use with Python and integrated into the project as a Python class. The project is created using the Eclipse IDE. This serves as an editor and debug tool for programming and implementing the functions and logic behind the graphical user interface of the visual programming tool. Python 3.4 is used as the programming language.
Thus, the following tools are used to create the visual programming tool, which are now presented below.
Amazon Purchase Links:
*Please Note: These are affiliate links. I may make a commission if you buy the components through these links. I would appreciate your support in this way!
Python 3.4:
Python is a universal and dynamic programming language that supports object-oriented, aspect-oriented and functional programming. The platform-independent Python interpreter is freely available and, thanks to the standard library supplied, enables Python programs to be embedded in other programming languages. Graphical user interfaces can be created with the help of the included Tkinter module or with so-called wrappers as bindings to GUI libraries such as PyQt. (Python Software Foundation, 2017)
One advantage over comparable programming languages is the dynamic data type management instead of the otherwise usual static type check such as with C ++. The Python interpreter also supports an interactive mode in which results are immediately visible and expressions can be entered directly on the terminal. Thus, code sections can be tested interactively before they are implemented.
Furthermore, numerous full-fledged development environments (IDEs) have been developed for Python, such as PyCharm. For larger IDEs like Eclipse or Visual Studio there are also plug-ins for using Python.
PyQt5:
PyQt5 is a toolkit that supports the creation of graphical user interfaces using Python. It serves as a “mediator” between the Python Qt C ++ cross-platform applications framework and the cross-platform programming language Python. This combines the advantages of the Python Qt library and Python.
Python Qt designer:
The Python Qt Designer is used to develop surfaces with the help of the Qt Framework and is an integrated part of the Python Qt Creator. This is a C ++ / Qt development environment (IDE) for Windows, Mac OS X and Linux. Due to the platform independence of the Qt library, programs can also be executed on other platforms without having to change the source code. This property is called “source code portability”.
The Python Qt Designer is a so-called WYSIWYG6 editor. This means that changes to the graphical user interface are immediately visible to the user. Accordingly, the source code is automatically created and updated during the write process of the Python Qt application. With the help of the Python Qt framework, the Python Qt Designer is used to create graphical user interfaces, which are initially saved as XML files. When creating graphical user interfaces, the first step is to select a window type on which objects can then be placed. With the help of so-called layouts it can be ensured that the created objects are displayed correctly even if the window size changes. The objects created are then listed in the “Object display” and can be further defined in the “Properties” window. A resource file can be created under “Resources” so that the management of integrated resources such as images or symbol files is possible.
In order to implement an event-controlled program flow or event-controlled communication between program elements, the elements or actions must be linked to one another. This is achieved through the signal slot concept. An element sends a signal after a certain event (e.g. after a mouse click). The previously connected slot (function) of another element is then called. These links can be partial
can be heard using the Python Qt Designer. However, the Python Qt Designer only supports predefined Qt functions, so that user-defined signals and slots cannot be connected via the graphical user interface and therefore have to be implemented manually by the programmer. (Summerfield, 2007)
3.1.4. Eclipse (IDE):
Eclipse is a freely available IDE, which is suitable for the development of various types of software due to many open source and commercial extensions.
Eclipse was originally used as an integrated development environment (IDE) for Java, so that the majority of the extensions in the “Java Development Tools” project are combined as plug-ins. In addition to the Java Development Tools, other projects can also be found on the Eclipse website. This includes the Eclipse Tools project, which contains various tools that developers can extend. The Eclipse Modeling Framework (EMF) project is ideal for creating data models that can be based on UML7. The Graphical Editing Framework (GEF) allows developers to create graphical editors from existing data models.
It is thus possible to put together suitable Eclipse bundles for specific projects, which only contain the necessary extensions or parts of Eclipse. This significantly relieves the main memory and the computing power.
The PyDev plug-in from the Eclipse Marketplace is required to use the Python programming language in conjunction with the Eclipse IDE. This plug-in enables Eclipse to be used as a Python IDE.
Creation of a graphical user interface for the script editor:
As a basis for creating the graphical user interface, was created in a GUI file with the help of the PYTHON QT Designer. below shows the Qt Designer with the PythonPictureScriptEditor project file open. The left part shows the main window of the visual programming tool to be developed. The right part shows a list of the created objects and their classes.
In the first step, a layout is placed on the main window in which all subsequent objects are placed. This is necessary for the size scalability of the objects and the changeability of the size of the complete window. In the following, a new layout is always created first for an area in which new objects are created. This ensures that the objects are displayed in the correct positions. After placing the objects, they will be unique Assign object names so that they can later be clearly referenced from the source text.
The following objects, which provide the basic functionality of the Script Editor, are created. This is a menu bar of the type QMenuBar, which is divided into three menu items of the type QMenu. The first menu item “File” includes the QAction objects for creating a new project, for saving and loading the current project and for closing the program. The second menu item “Edit” provides the QAction object for opening the options window. The third option of the menu bar “Help” provides a QAction to open a window with information about the script editor.
Various QPushButton objects were also created. Two of the buttons, for creating a new script and for deleting a script, are arranged above the created script list of type QTreeWidget. The remaining five buttons are created above the work area and are intended to be linked to methods for loading an image, executing the scripts, grouping several nodes and deleting nodes or edges on the work area. The work area is of the type QGraphicsView, so that drawing on this object is possible.
After the graphical user interface has been created, it is first saved in XML format. In the next step, this file must be compiled into a Python class so that it can be used in the actual source code of the Visual Programming Tool. This means that the individually created elements of the graphical user interface can now be accessed in the source code.
The compilation creates the Python file PythonPictureScriptEditor.py, which provides the Ui_MainWindow class. This class contains the setupUi (MainWindow) method, which implements the objects created in the Python Qt Designer and their object properties.
After the required graphical user interface has been created with the help of the Python Qt Designer and compiled into Python format.
First, the Main class (QtWidgets.QMainWindow) is created to import the graphical user interface there. The main window Ui_MainWindow created in the PythonPictureScriptEditor.py file is created in the Main class. The class is also used to manage the objects in the graphical user interface. In the __init__ method of the Main class, which is called immediately after the construction of the object and thus initializes the object of the Main class, the QPushButton and QMenu objects are initially empty using the signal-slot concept connected.
Implementation of the work area:
So that it is possible to draw objects on the work area, the class DeskGraphicScene (QtWidgets.QGraphicsScene) is now created. This class creates what is known as a scene on which objects can be drawn. This scene forms the basis for all objects, i.e. for the nodes and edges that are created by the user. For this reason, after creating this object, an empty Dictionary8, the drawableList, is initialized for these objects. Furthermore, methods for adding nodes addNode and edges addEdge as well as a method for drawing all objects drawAll stored in the drawableList are implemented. The method drawAll must be called for correct display on the scene after every change and after every addition of an object to the drawableList. It thus serves as a “refresh” function for the scene.
When creating the concept of the classes, the classes, which provide methods for displaying graphic elements, were combined in the UI package. For this reason, this package will be created in the next step and the class DeskGraphicScene (QtWidgets.QGraphicsScene) will be moved into it. The other classes for displaying graphic elements such as nodes or edges in the UI package are then also created.
In order to draw a node or an edge on the scene, a new class Drawable is created, which contains the basic methods of an object for display on the scene in Implementation of the context of the script editor. A method draw (self, xPos, yPos) is used to draw an object at the transferred x and y positions, a method isAtPosition (self, xPos, yPos) which checks whether the object is located at the transferred position and a Method move (self, xPos, yPos) created to change the current position of the object. In addition, a unique identification number, an ID, is created in this object, so that each drawable object can always be clearly identified and changed during program execution. Thus this class serves as a super class for the nodes and edges and possible other objects that should be drawn on the scene. For this reason, the classes Node (Drawable) and Edge (Drawable) are created below. These classes are derived from Drawable and thus receive all the functionalities of the Drawable class. This technique is a basic concept in object-oriented programming and is called inheritance.
Inheritance is used in object orientation to create new classes based on these classes or expanding them from existing classes. This creates relationships between two classes, the super class and the derived class. This relationship allows the super class, i.e. the original class, to extend methods or to restrict them in certain points.
At this point in development it is possible to draw simple nodes and connect them with edges.
Since it is defined in the requirements that edges must be able to be drawn from an output parameter of a script node to an input parameter of another node, there are now two ways of doing this. On the one hand, the Node (Drawable) class can be expanded so that methods are implemented there that control the input and output Draw parameters. In this case, another method for checking the position of the input and output parameters, e.g. isInputOrOutputAtPosition (self, xPos, yPos), would have to be created in the Node (Drawable) class so that the edges can be drawn correctly from these points . On the other hand, there is the possibility of creating two new classes, which also inherit from the Drawable class and are created with the methods required for checking the position and for drawing, as described in the first variant.
In order to maintain the clarity and the structure already created in the Package UI, the second option for implementing input and output parameters is chosen. So first two new classes are created. The NodeInput (Drawable) and NodeOutput (Drawable) classes differ essentially in the way in which they read the required parameters from the script that is stored in the node. For this reason, a getValue method is implemented in the NodeInput (Drawable) class, with the help of the outputSource variable stored in the NodeInput object, which represents the connected NodeOutput object, reads out the required value and returns it as a return value. Thus, the getValue method of the NodeOutput (Drawable) class does not need any knowledge of which NodeInput object it is connected to, but can return the defined parameter as a return value. The NodeInput and NodeOutput objects are shown as small circles on the left (input) and right (output) side of the node objects.