source: src/documentation/constructs/qt-gui.dox@ 52c5d4

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 52c5d4 was 52c5d4, checked in by Frederik Heber <heber@…>, 9 years ago

DOCU: Updated documentation on Qt Gui construct.

  • Property mode set to 100644
File size: 12.9 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/**
9 * \file qt-gui.dox
10 *
11 * Created on: Jan 5, 2012
12 * Author: heber
13 */
14
15/**
16 * \page qt-gui Qt GUI
17 *
18 * The Qt GUI is the most advanced interface and thus the most complex.
19 *
20 * In the following we want to explain some of the details that are involved.
21 *
22 * \section qt-gui-general General Concepts
23 *
24 * Let us first discuss about the general concepts.
25 *
26 * MoleCuilder is about atoms, bonds and the molecules made up by them. But
27 * there is more: There are fragments, potentials, shapes, and so on.
28 *
29 * In the Qt GUI all of these are displayed in certain areas of the screen
30 * and also in a certain manner:
31 * -# the 3D view represents a three-dimensional representation of all atoms,
32 * and their bonds or possibly the molecules they form alone. Also the
33 * bounding box is shown and all selected shapes. Atoms or molecules can
34 * be selected by clicking. The view can be manipulated through rotation
35 * and translation.
36 * -# an element list shows all available elements of the period table.
37 * -# a molecule list shows all present molecules sorted by their formula.
38 * -# a fragment list shows all fragments with their energies and contributions
39 * -# a potential list shows all currently instantiated potentials and
40 * gives a 2D plot.
41 * -# a shape list displays all currently available shapes, allows to select
42 * them and buttons allow to combine them via boolean operation.
43 * -# an info box informs about the current atom/molecule the mouse pointer
44 * is hovering over.
45 *
46 * So, there are many objects that need to be filled with information and
47 * they need to access the World and other singletons in order to obtain
48 * this information.
49 *
50 * One major obstacle, or rather THE major obstacle, is that Qt is threaded,
51 * i.e. the Actions are processed in one thread and the Gui does its event
52 * processing in another one. Qt's Signal/Slot system is handled via this
53 * event system, i.e. a signal launched by one thread may be handled by
54 * the slot function in another thread. The Observer/Observable system
55 * of the CodePatterns which we used internally/outside Qt's scope does
56 * not do this.
57 *
58 * Also, signals may get delayed. This can happen either deliberately, e.g.
59 * there is a QTimer that only updates an object in regular intervals, or
60 * because of asynchronous threads. Elsewhen, the slot callback for a
61 * certain signal is called directly. For all of these cases we have to
62 * accommodate. This is especially problematic with the instantiation and
63 * destruction of objects.
64 *
65 * A clarifying example: Imagine an atom is constructed, the AtomObserver
66 * notifies about it, but the information is not processed immediately.
67 * Shortly after, the atom is destroyed again before its representation is
68 * instantiated in the GUI. Afterwards the GUI attempts to instantiate it
69 * but can not longer access the atom for its position and element.
70 *
71 * The only possible way out is to duplicate information. This is the usual
72 * way how to deal with environments with multiple threads. I.e. all the
73 * information that the GUI representants of information inside the World
74 * needs to be doubled such that when the original information is destroyed
75 * the representant can still be accessed as long as needed.
76 *
77 * \subsection qt-gui-general-observedvalue Observed Value
78 *
79 * These representants are called \a ObservedValue in CodePatterns and they
80 * are used everywhere in the Qt Gui.
81 *
82 * They contain an internal information, e.g. a boolean, a Vector or even
83 * a complex structure such as a Tesselation. They require an updater
84 * function to obtain the derived information from the original source. And
85 * they signOn to the source in order to be notified either generally on
86 * updates or for specific channels only.
87 *
88 * The ObservedValue will automatically and immediately update its internal
89 * representation of the derived information by calling the updater function
90 * as soon as it has been informed about the update. Hence, the internal
91 * information is always up-to-date and lives beyond the scope of the
92 * source of the information until its own destruction. As updates are
93 * processed immediately, this pattern only makes sense for "small" pieces
94 * of information, i.e. when the updater function is very light-weight and
95 * does not do much in terms of using computing resources.
96 *
97 * Note that there is another concept that is opposite to the observed value,
98 * namely the Cacheable. This pattern will update itself only when requested,
99 * referred to as "lazy evaluation". Hence, this pattern is used for "large"
100 * pieces of information that require more computing resources within the
101 * updater. Also, the Cacheable's information can only be obtained as long
102 * as the source of information is still alive.
103 *
104 * Both concepts can be used in threaded environments as mutexed are used to
105 * protect read and write accesses.
106 *
107 * \subsection qt-gui-general-signalslot Observer/Observable and Signal/Slot
108 *
109 * In the following we refer to Observer/Observable as "O/O" and to Signal/Slot
110 * as "S/S".
111 *
112 * One thing we need to do is to translate between update() or
113 * recieveNotification() calls from an Observable and subsequent signal/slot
114 * calls. The general idea is to use these ObservedValues as translation
115 * points for small pieces of information and Cacheables for larger pieces.
116 *
117 * However, we need more of these translation points:
118 * -# GLWorldView checks for
119 * -# World's MoleculeInserted
120 * -# World's SelectionChanged
121 * -# WorldTime's TimeChanged
122 * -# each molecule's AtomInserted and AtomRemoved
123 * -# AtomObservable's AtomChanged.
124 * -# ShapeRegistry's ShapedAdded, ShapeRemoved, and SelectionChanged
125 * -# GLMoleculeObject_molecule checks for
126 * -# molecule's AtomInserted, AtomRemoved, AtomMoved, IndexChanged
127 * -# World's SelectionChanged
128 *
129 * \section qt-gui-qt3d Qt3D and the way to get atoms and bonds displayed
130 *
131 * By far the most difficult component of the Qt GUI is the 3D view. So,
132 * let us explain it in detail.
133 *
134 * The general widget making up the view is called \a GLWorldView. It contains
135 * the GLWorldScene (i.e. all atoms, bonds, molecules, and shapes). Also
136 * the "dreibein" and the domain. It processes key presses and mouse events
137 * to manipulate the view. And it also serves as the translator O/O to S/S
138 * system.
139 *
140 * The GLWorldScene contains the actual nodes of the molecular system, i.e.
141 * the atoms, bonds, molecules, and shapes. All of these are derived from
142 * GLMoleculeObject and have their parent to the instance of the GLWorldScene
143 * which goes through its list of children and to call draw() on them.
144 *
145 * The bottom-most structure is GLMoleculeObject_atom displaying a sphere
146 * of an element-specific color at the atom's position. The atom relies
147 * on its representants to be contain all required information but it
148 * is also signOn() to the atom itself whose O/O are translated to S/S
149 * for processing whenever desired.
150 *
151 * Next comes the GLMoleculeObject_bond which displays a cylinder between
152 * two atoms. Actual, a true bond consists of two of these objects. If the
153 * bond is between heterogeneous atoms each half will be displayed in the
154 * color of the closer atom. These bond objects are not associated with
155 * the atoms directly as the are linked to two atoms at the same time. They
156 * rely on ObservedValues for position and element of either atom and for
157 * the degree of the bond itself.
158 *
159 * Parallel to these are GLMoleculeObject_shape which display the surface
160 * of a selected shape. A shape in general does not change after instantation,
161 * hence the shape lives with the information it gets on instantiation till
162 * it dies.
163 *
164 * Finally, the GLMoleculeObject_molecule owns both atoms and bonds. This
165 * allows for switching the view between the classical ball-and-stick model
166 * and the tesselated surface of the molecule. The latter uses a lot less
167 * triangles and thus is faster. Also, it is especially suited for large
168 * molecules. The molecule also needs ObservedValues for its bounding box
169 * (used to show when it's selected), the index, the selection status,
170 * and the list of atom ids. As Cacheable we use the tesselation structure.
171 *
172 * \section qt-gui-cases Sample cases
173 *
174 * Let us discuss some cases and how the different instances interact.
175 *
176 * \section qt-gui-cases-start Start
177 *
178 * When molecuilder is started, several singletons such as the World and
179 * others are instantiated. No atoms are yet present, no bonds, no molecules.
180 * Hence, nothing to display yet.
181 *
182 * Before launching any Action the ActionQueue is forced to wait till the
183 * GUI is finished instantiating. This is to ensure that GLWorldView and
184 * others are in place to receive signals from the O/O system.
185 *
186 * When a molecule is loaded, the instantiation of a GLMoleculeObject_molecule
187 * does not happen immediately. Hence, GLWorldView listens to the World's
188 * MoleculeInserted. On receiving it, it also signOn()s to the molecule
189 * to get its subjectKilled(). It translates then these and also all
190 * AtomInserted and AtomRemoved to the S/S system as moleculeInserted,
191 * moleculeRemoved and atomInserted/atomRemoved respectively, which are
192 * processed by the GLWorldScene.
193 *
194 * The GLWorldScene records any atomInserted/atomRemoved until the molecule
195 * has been instantiated. On instantiation all recorded events are played.
196 * This is to ensure that there is no overlap in instantiation and signOn()
197 * to the molecule. If we would simply get all atoms which are present
198 * on processing the molecule's instantiation we might stumble over a signal
199 * of a molecule of a just added atom. This occurs frequently as both
200 * are very much correlated.
201 *
202 * GLWorldView keep track of all ObservedMolecules. And GLWorldScene keeps
203 * track of all shapes and molecules in the scene. Each
204 * GLMoleculeObject_molecule in turn keeps track of all atoms and bonds in
205 * its part of the scene.
206 *
207 * \section QtElementList
208 *
209 * Lists for each element how often it occurs in the world. Selecting an entry
210 * calls SelectionAtomByElementAction to select all atoms of that particular
211 * element.
212 *
213 * Initially, it fills itself by looking at all elements in the World's
214 * periodentafel. It also listens to AtomObserver's ElementChanged to know
215 * when to update a certain element in its list. By using an internal list
216 * for each atom's element, it can update each element's occurrence.
217 *
218 * \section QtMoleculeList
219 *
220 * Lists all the molecules currently in the world grouped by their formula.
221 * Selecting an entry calls the SelectionMoleculeByIdAction.
222 *
223 * The QtMoleculeList is also a rather complex beast. It is a tree of
224 * rows and each row consists of a number of elements. There are two
225 * levels, the group level where the common formula for all molecules
226 * is given, and the molecule level where are molecules of this specific
227 * formula are summarized.
228 *
229 * The group items are QStandardItems. Sadly, they are not derived from
230 * QObject and hence do not use the S/S system. The group items are
231 * directly controlled by the QtMoleculeList.
232 *
233 * However, the molecule items are different. They are derived from
234 * QtMoleculeList and use an ObservedValue internally to contain an always
235 * valid copy of the required information. They inform the QtMoleculeList on
236 * updates via a callback (as QStandardItem, from which they are also derived,
237 * does not use the S/S system). The callback takes care of then also updating
238 * the group items and possibly moving the molecule items around, e.g. if
239 * their formula has changed they suddenly belong to another group.
240 *
241 * All items are instantiated by the QtMoleculeItemFactory.
242 *
243 * QtMoleculeList uses an internal QTimer to only update itself at regular
244 * intervals. Hence, updates are processed rather lazily. We keep lists
245 * of changes, separated for group and molecule items. And these are processed
246 * one after the other at the intervals dictated by the QTimer in
247 * updateItemStates().
248 *
249 * \section QtShapeController
250 *
251 * This is the interface for the ShapeRegistry. It lists all the shapes in the
252 * registry and lets the user select them. It also features buttons to call
253 * actions creating and manipulating the selected shapes.
254 *
255 * As an Observer it handles the following messages from ShapeRegistry:
256 * - ShapeRegistry::ShapeInserted
257 * - ShapeRegistry::ShapeRemoved
258 * - ShapeRegistry::SelectionChanged
259 *
260 * \section QtInfoBox
261 *
262 * Shows information about the atom and molecule the cursor is currently hovering
263 * over inside the GLWorldView.
264 *
265 * GLWorldView emits hoverChanged signals (via QT's signal slot mechanism) which
266 * the QtInfoBox receives. QtInfoBox then creates its info pages for the atom
267 * being transmitted as the signal's parameter.
268 *
269 * The info pages are Observers for the atom/molecule. When recieving subjectKilled
270 * they automatically clear the info box.
271 *
272 * \date 2015-07-15
273 */
Note: See TracBrowser for help on using the repository browser.