Author Topic: Newest Ovito (2.8.x) crashes running a Python script with PyQT5  (Read 1877 times)

RU

  • Newbie
  • *
  • Posts: 12
Newest Ovito (2.8.x) crashes running a Python script with PyQT5
« on: December 20, 2016, 02:33:59 PM »
Hey,
i am using Ovito for the visualization of atomistic simulation and for postprocessing purposes. Thats why i like the function of running python scripts to process individual task or calculate some values im interested in. For this postprocessing i created an popup window with the PyQt5 plugin showing some result values.

Unfortunately these scripts are crashing with the newest versions (2.8.x).

I tried a lot of hints and modifications for the script, which i found for similiar problems, but none of these worked for me.
I attached a small example script, showing a popup window with 'Hello World!', which works fine unter Ovito 2.7.1, but not with the newest versions.

Maybe someone got an idea whats wrong?
Or maybe Mr. Stukowski can give me a hint, whats the problem or difference with the newest version?

Best regards

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 638
Re: Newest Ovito (2.8.x) crashes running a Python script with PyQT5
« Reply #1 on: December 20, 2016, 05:17:25 PM »
Hi,

Note that Ovito already creates its own QApplication object. The same is true for the ovitos script interpreter. The internal QApplication object exists while the script is being executed.

It is therefore not a good idea to create a second QApplication from the script (Qt only allows a single QApplication instance). The segmentation fault results from Ovito trying to delete its QApplication object after script execution. However, this object has already been auto-deleted by Qt, because the script created a second QApplication object.

The solution to this problem is to not create a second QApplication instance. Instead, simply access the existing one from the script:

Code: [Select]
if __name__ == '__main__':
    app = QApplication.instance()
    ...
    sys.exit(app.exec_())


(Older Ovito versions didn't try to delete the QApplication object upon program exit. Thus, creating a second QApplication object from the script, even though wrong, didn't result in a segfault.)

RU

  • Newbie
  • *
  • Posts: 12
Re: Newest Ovito (2.8.x) crashes running a Python script with PyQT5
« Reply #2 on: December 22, 2016, 03:17:29 PM »
Hey,

thanks for the quick answer!

But my script still not work as expected. Now the popup window closes immediately after it is created.
I figured out that the command
Code: [Select]
app.exec_()returns '-1', which indicates that there is an error or that somethind didnt quit correctly.

Maybe you have a guess whats the problem with it?
Research on the internet didnt helped me, because it seems that the case, where an existing QApplication is used is pretty rare.
Im also not sure if the command
Code: [Select]
app.exec_()makes sense in this case, because the main instance of QApplication is already executed?
So i dont know how to deal with the existing instance of QApplication, and how to connect my popup window with it.

The minimal code is the following:
Code: [Select]
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
if __name__ == '__main__':
    app = QApplication.instance()
    window1 = QWidget()
    window1.setWindowTitle("Hello World!")
    window1.show()
    sys.exit(app.exec_())   

Best regards

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 638
Re: Newest Ovito (2.8.x) crashes running a Python script with PyQT5
« Reply #3 on: December 22, 2016, 03:32:56 PM »
Hmm, the minimal code example that you posted works for me when I run it with the ovitos interpreter (Ovito version 2.8.1, Linux). It shows a window, and the script waits until I manually close the window. Please let me know if you are trying this on a platform other than Linux. Maybe it is a platform-specific issue.

RU

  • Newbie
  • *
  • Posts: 12
Re: Newest Ovito (2.8.x) crashes running a Python script with PyQT5
« Reply #4 on: December 22, 2016, 03:35:41 PM »
Hey,

im running Ovito on Windows, and run the code with the 'Scripting>Run Script File option' from the Ovito main window.
I am not using the ovitos command line.

Best regards

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 638
Re: Newest Ovito (2.8.x) crashes running a Python script with PyQT5
« Reply #5 on: December 22, 2016, 04:09:33 PM »
I see, you want to run the script from within Ovito. This requires a different approach, because Ovito has already called QApplication::exec() and the script is executed within the running event loop. However, Qt allows you to start a local event loop. The loop can be stopped again by some signal (in this case: the window being closed by the user). Here is a demo script:

Code: [Select]
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
if __name__ == '__main__':
    app = QApplication.instance()
    window1 = QWidget()
    window1.setWindowTitle("Hello World!")
    window1.show()

    event_loop = QEventLoop()
    window1.setAttribute(Qt.WA_DeleteOnClose)      # Make sure window is destroyed when user closes it.
    window1.destroyed.connect(event_loop.quit)     # Quit local event loop when window is destroyed.
    QTimer.singleShot(100, lambda: window1.activateWindow())     # Wait for a short time, then bring window in front of all other windows.
    event_loop.exec()     # Start local event loop.


One problem I noticed with this approach: If you abort the script execution by pressing "Cancel" instead of closing the window, the local event loop is never orderly terminated. This seems to cause a program crash when Ovito is quit.
« Last Edit: December 22, 2016, 04:40:55 PM by Alexander Stukowski »

RU

  • Newbie
  • *
  • Posts: 12
Re: Newest Ovito (2.8.x) crashes running a Python script with PyQT5
« Reply #6 on: January 03, 2017, 02:16:33 PM »
Thanks for the answer, that helped a lot!

Happy New Year 2017!