Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-1178

Replacing the qApp "macro" by a no-surprizes qApp callable?



    • Type: Task
    • Status: Closed
    • Priority: P3: Somewhat important
    • Resolution: Done
    • Affects Version/s: 5.14.0
    • Fix Version/s: None
    • Component/s: PySide, Shiboken
    • Labels:
    • Commits:
      8c5b08a74650e5dea7303d6f232c4df0f706cb35 (pyside/pyside-setup/5.14)


      qApp present implementation

      The qApp macro has been invented in 2017 as the attempt to produce a "macro" in Python.
      Macros are not possible, but the behavior of qApp tried to mimick the C++ equivalent as much as possible.

      In order to accomplish that, a quite uncommon trick was used: The qApp variable was implemented as a singleton variable that could change its content completely. This variable existed for compatibility in QtCore, QtGui, QtWidgets, but mainly in the builtins! So this variable could be used directly after importing PySide2.

      The basic advantage of this was: By writing


      , you got the content of Q*Application.instance() immediately.
      You could also delete the application by

      del __builtins__.qApp

      There were no properties used and no function calls. qApp was just passively in the right place.

      This also had drawbacks: When no application was initialized, we could not put the singleton None into qApp because it is a singleton itself. We used an object with PyNone_Type and boolean value False, but that was probably too confusing.

      We could easily change that by providing a i.e. NoApp object, but that is a minor issue.

      The real problem:

      The qApp macro had quite good behavior and was considered to stay this way. But when using embedded applications, :Pjects.

      • the assignment of qApp is therefore not flexible, but must be correct in the first place. For that reason,
      • the timing problem could not be solved for PYSIDE-1135. qApp assigns QApplication.instance() too early, which breaks the Falcon application.

      This is the reason to abandon the whole qApp implementation: Because we can't find a general solution in the embedded case that works in every configuration, here the proposed, incompatible change:

      The new qApp function (Proposal)

      The reason why we supported qApp at all was brevity. You always can write QApplication.instance() instead. Therefore, also properties make not much sense. Besides the problem that modules cannot have properties easily before Python 3.7, having to write QtWidgets.qApp is long. The easiest way out of the dilemma is this:

      qApp is now a regular function object that must be imported from QtWidgets. the usage


      is equivalent to


      It is still possible to delete an application by calling

      Before After
      qApp qApp()
      del _builtins_.qApp qApp.shutdown()
      qApp is also in QtCore QtGui QtWidgets

      Alternate Proposal

      Another, less intrusive approach is to keep qApp almost as it is. Only two things are changed:

      • when qApp returned "None", it now says "noApp". The type is still NoneType.
      • deletion is implemented now as qApp.shutdown()

      There is still a problem with the "Falkon" browser reported. This will probably be fixable in Falkon, or as last resort we disable qApp when embedding (which avoids imports during initialization).

      Update: Final Solution

      We do the alternate implementation, with the following addition:
      qApp does no longer exist in embedded mode. This solves all problems


          Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.



              ctismer Christian Tismer
              ctismer Christian Tismer
              0 Vote for this issue
              2 Start watching this issue



                  Gerrit Reviews

                  There are no open Gerrit changes