58

I use Python 3 and PyQt5. Here's my test PyQt5 program, focus on the last 2 lines:

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys

class window(QWidget):
def __init__(self,parent=None):
    super().__init__(parent)
    self.setWindowTitle('test')
    self.resize(250,200)

app=QApplication(sys.argv)
w=window()
w.show()
sys.exit(app.exec())
#sys.exit(app.exec_())

I know exec is a language keyword in Python. But code on Official PyQt5 Documentation (specifically the Object Destruction on Exit part). I see that example shows use of app.exec() which confuses me.

When I tested it on my machine. I found there is no any visible difference from my end. Both with and without _ produces the same output in no time difference.

My question is:

  • Is there anything wrong going when I use app.exec()? like clashing with Python's internal exec? I suspect because both exec's are executing something.
  • If not, can I use both interchangeably?
Santosh Kumar
  • 26,475
  • 20
  • 67
  • 118
socket
  • 1,153
  • 3
  • 13
  • 22
  • 17
    In PyQt5, you don't need `sys.exit()` at all. `app.exec_()` or `app.exec()` alone is enough and it works normally. They fixed some things in PyQt5 under the hood so that you don't need that `sys.exit()` anymore. If you want your code to run on PyQt4, then have `sys.exit()` there. Also, `app.exec_()` and `app.exec()` are interchangable, so you can use whichever you like. If you want your code to run on PyQt4 as well, then stick with `app.exec_()`. So, the bottom line is: for your code to work properly on PyQt5 **and** PyQt4, use `sys.exit(app.exec_())`. – Boštjan Mejak Nov 16 '17 at 18:28
  • @ Boštjan Mejak.. hoora for your comment and explenation! More upvotes needed for sure! First comment so far I found that explains these minor differences that I noticed in the code. The change from pyqt4 to pyqt5 is like learning to read again (have to admit.. 10 years not programming makes one a bit rusty.. and python popping a few funballs under the hood too). – ZF007 Dec 05 '17 at 12:36
  • 4
    @BoštjanMejak: you do need `sys.exit()` otherwise `app.exit(1)` call doesn't lead to the corresponding exit status i.e., even on Python 3 and PyQt5, use `sys.exit(app.exec())`. – jfs Jan 10 '18 at 09:11
  • In PyQt5, they’ve fixed the order in which Qt and Python stop their process and so now we really don’t need to use sys.exit() call anymore. It’s all explained in the PyQt5 documentation. – Boštjan Mejak Jan 19 '18 at 10:49
  • 2
    @BoštjanMejak: *wrong*. Here's a [minimal code example](https://gist.github.com/zed/7219ddf356e25bfd9527c2762729b5d3). btw, use \@ syntax if you want me to be notified about your comments. – jfs Jan 26 '18 at 15:00

3 Answers3

112

That's because until Python 3, exec was a reserved keyword, so the PyQt devs added underscore to it. From Python 3 onwards, exec is no longer a reserved keyword (because it is a builtin function; same situation as print), so it made sense in PyQt5 to provide a version without an underscore to be consistent with C++ docs, but keep a version with underscore for backwards compatibility. So for PyQt5 with Python 3, the two exec functions are the same. For older PyQt, only exec_() is available.

Oliver
  • 27,510
  • 9
  • 72
  • 103
8

On the question of whether to prefer one over the other: using exec_ means you have one less thing to worry about if you ever decide to add support for PyQt4 and/or Python >= 2.6, and want to maintain a single code-base.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • 1
    I think you mean Python <= 2.99, right? (Or Python2 >= 2.6.). – FeRD Mar 30 '18 at 06:26
  • @FeRD. No. I mean that `exec_` will work with any version of python equal to or greater than 2.6 in combination with either pyqt4 or pyqt5. Earlier versions of python are not supported by pyqt. So `exec_` is both forwards and backwards compatible with both pyqt4 and pyqt5, and any version of python >= 2.6 (I doubt whether python-3.0.x is really viable, though). – ekhumoro Mar 30 '18 at 16:14
2

As of PyQt 6, app.exec_() is no longer supported, only app.exec() is.

Hence, when building new apps I only use the latter.

https://www.riverbankcomputing.com/static/Docs/PyQt6/pyqt5_differences.html?highlight=pyqt5

eric
  • 7,142
  • 12
  • 72
  • 138
  • but what should I do instead? – eri0o Jan 24 '22 at 14:10
  • I've clarified my answer. OP wanted to know whether to use `app.exec()` or `app.exec_()`. Since `app.exec_()` is no longer supported, I only use `app.exec()` in new apps. It just makes things simpler moving forward. – eric Jan 24 '22 at 19:35